0
votes

Stripe's iOS SDK's "STPPaymentCardTextField" has 4 fields for generating a token for a card : 1. credit card number 2. expiration month 3. expiration year 4. CVC field

We are saving only credit card number and expiration month/year. We don't need to get CVC number from user. So how to hide or remove CVC field from STPPaymentCardTextField.

Please give me some idea to handle this process.

2

2 Answers

1
votes

it is possbile but we need to do this carefully , ok open STPPaymentCardTextField.m file and you get the property of CVC field name as STPFormTextField

@property(nonatomic, readwrite, weak)STPFormTextField *cvcField; 

finally hide related to cvcField where ever it comes on that page around it occupy the 21 Places in that page , for e.g

STPFormTextField *cvcField = [self buildTextField];
cvcField.tag = STPCardFieldTypeCVC;
cvcField.alpha = 0;
self.cvcField = cvcField;
self.cvcPlaceholder = @"CVC";
[self.fieldsView addSubview:cvcField];

- (void)setCvcPlaceholder:(NSString * __nullable)cvcPlaceholder {
_cvcPlaceholder = [cvcPlaceholder copy];
self.cvcField.placeholder = _cvcPlaceholder;
}

else make a trick hide

[self.fieldsView addSubview:cvcField];
1
votes

First way: Modifying the framework source

If you are fine with modifying the framework source, you can do this actually way easier:

In STPPaymentCardTextField.m change

self.allFields = @[numberField,
                   expirationField,
                   cvcField,
                   postalCodeField];

into

self.allFields = @[numberField,
                   expirationField,
                   postalCodeField];

and in STPPaymentCardTextFieldViewModel.m change

- (BOOL)isValid {
    return ([self validationStateForField:STPCardFieldTypeNumber] == STPCardValidationStateValid
            && [self validationStateForField:STPCardFieldTypeExpiration] == STPCardValidationStateValid
            && [self validationStateForField:STPCardFieldTypeCVC] == STPCardValidationStateValid
            && (!self.postalCodeRequired
                || [self validationStateForField:STPCardFieldTypePostalCode] == STPCardValidationStateValid));
}

into

- (BOOL)isValid {
    return ([self validationStateForField:STPCardFieldTypeNumber] == STPCardValidationStateValid
            && [self validationStateForField:STPCardFieldTypeExpiration] == STPCardValidationStateValid
            && (!self.postalCodeRequired
                || [self validationStateForField:STPCardFieldTypePostalCode] == STPCardValidationStateValid));
}

Second way: Subclassing STPPaymentCardTextField

I don't like editing a framework since I like to update, so I did it this by subclassing STPPaymentCardTextField (example in Swift):

class STPPaymentCardTextFieldNoCVC: STPPaymentCardTextField {

  func removeCVC() {
    if let fieldsView = subviews.first {
      for view in fieldsView.subviews where view.tag == 2 {
        // set a default cvc for the validator and remove the field
        (view as? UITextField)?.text = "123"
        view.removeFromSuperview()
      }
    }
  }

  required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    removeCVC()
  }

  override init(frame: CGRect) {
    super.init(frame: frame)
    removeCVC()
  }
}