【问题标题】:Validating credit cards using Stripe with iOS在 iOS 中使用 Stripe 验证信用卡
【发布时间】:2016-01-13 06:47:01
【问题描述】:

我开始将 Stripe 集成到我正在制作的 iOS 应用程序中,并且我已经到了需要验证卡信息的地步。

我试过了:

#pragma mark - My Actions

- (IBAction)buyButtonTapped:(id)sender {

  //Populate STPCard property
  self.stripeCard = [[STPCard alloc]init];
  self.stripeCard.name = self.txtFieldCardHolderName.text;
  self.stripeCard.number = self.txtFieldCardNumber.text;
  self.stripeCard.cvc = self.txtFieldCardCvc.text;
  self.stripeCard.expMonth = [self.selectedMonth integerValue];
  self.stripeCard.expYear = [self.selectedYear integerValue];

  //Validate Customer info
  if ([self validateCustomerInfo]) {
    [self performStripeOperation];
  }

} 

-(BOOL)validateCustomerInfo{

  //Create Alert

  UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Please, try again!"
                                                                 message:@"Please, enter all required information."
                                                          preferredStyle:UIAlertControllerStyleAlert];

  UIAlertAction *action = [UIAlertAction actionWithTitle:@"OK"
                                                   style:UIAlertActionStyleDefault
                                                 handler:^(UIAlertAction * _Nonnull action) {

                                                   //Add some action

                                                 }];

  //Add its action
  [alert addAction:action];


  //Validate text fields
  if (self.txtFieldCardHolderName.text == 0 || self.txtFieldCardNumber.text == 0 || self.txtFieldCardExpDate.text == 0 || self.txtFieldCardCvc.text == 0) {

    [self presentViewController:alert animated:true completion:nil];
    return NO;
  }

  //Validate card number, CVC, expMonth, expYear
  NSError *error = nil;

  [self.stripeCard validateCardReturningError:&error];

  //3
  if (error) {
    alert.message = [error localizedDescription];
    [self presentViewController:alert animated:true completion:nil];
    return NO;
  }

  return YES;

}

我在 StackOverflow 上检查了其他几个问题,似乎每个人都使用 validateCardReturningErrormethod,它在 iOS9 中已被弃用。

Xcode 抱怨并要求我改用 STPCardValidator。

谁能帮我举一个使用 STPCardValidator 验证卡的例子?

我注意到我也可以使用以下 Class 方法:

[STPCardValidator validationStateForNumber:self.txtFieldCardNumber.text validatingCardBrand:true];

但我不确定如何在我的 validateCustomerInfo 方法中使用它。

【问题讨论】:

  • 现在,STPCard 没有这些属性?

标签: ios objective-c stripe-payments


【解决方案1】:
- (IBAction)buyButtonTapped:(id)sender{

    param = [[STPCardParams alloc]init];
    param.number = txt_cc_no.text;
    param.cvc = txt_cc_cvvno.text;
    param.expMonth =[self.selectedMonth integerValue];
    param.expYear = [self.selectedYear integerValue];


   if ([self validateCustomerInfo]) {
       [self performStripeOperation];
   }

}
- (BOOL)validateCustomerInfo {

    //2. Validate card number, CVC, expMonth, expYear
    [STPCardValidator validationStateForExpirationMonth:[self.selectedMonth stringValue]];
    [STPCardValidator validationStateForExpirationYear:[self.selectedYear stringValue] inMonth:[self.selectedMonth stringValue]];
    if ([txt_cc_type.text isEqualToString:@"visa"]) {
        [STPCardValidator validationStateForCVC:txt_cc_cvvno.text cardBrand:STPCardBrandVisa];
        [STPCardValidator validationStateForNumber:txt_cc_no.text validatingCardBrand:STPCardBrandVisa];
    }
    else if ([txt_cc_type.text isEqualToString:@"MasterCard"]){
        [STPCardValidator validationStateForCVC:txt_cc_cvvno.text cardBrand:STPCardBrandMasterCard];
        [STPCardValidator validationStateForNumber:txt_cc_no.text validatingCardBrand:STPCardBrandMasterCard];
    }
    else if ([txt_cc_type.text isEqualToString:@"American Express"]){

        [STPCardValidator validationStateForCVC:txt_cc_cvvno.text cardBrand:STPCardBrandAmex];
        [STPCardValidator validationStateForNumber:txt_cc_no.text validatingCardBrand:STPCardBrandAmex];
    }
    else if ([txt_cc_type.text isEqualToString:@"Discover"]){
        [STPCardValidator validationStateForCVC:txt_cc_cvvno.text cardBrand:STPCardBrandDiscover];
        [STPCardValidator validationStateForNumber:txt_cc_no.text validatingCardBrand:STPCardBrandDiscover];
    }
    else if ([txt_cc_type.text isEqualToString:@"Diners Club"]){
        [STPCardValidator validationStateForCVC:txt_cc_cvvno.text cardBrand:STPCardBrandDinersClub];
        [STPCardValidator validationStateForNumber:txt_cc_no.text validatingCardBrand:STPCardBrandDinersClub];
    }
    else if ([txt_cc_type.text isEqualToString:@"JCB"]){
        [STPCardValidator validationStateForCVC:txt_cc_cvvno.text cardBrand:STPCardBrandJCB];
        [STPCardValidator validationStateForNumber:txt_cc_no.text validatingCardBrand:STPCardBrandJCB];
    }
    else if ([txt_cc_type.text isEqualToString:@"Unknown"]){
        [STPCardValidator validationStateForCVC:txt_cc_cvvno.text cardBrand:STPCardBrandUnknown];
        [STPCardValidator validationStateForNumber:txt_cc_no.text validatingCardBrand:STPCardBrandUnknown];
    }


    return YES;
}
- (void)performStripeOperation {
    [[STPAPIClient sharedClient] createTokenWithCard:param
                                          completion:^(STPToken *token, NSError *error) {
                                              if (error) {
                                                  //                                           [self handleError:error];
                                                  NSLog(@"ERRRRR = %@",error);
                                                  UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Please try again"
                                                                                                   message:[NSString stringWithFormat:@"%@",error.localizedDescription]
                                                                                                  delegate:nil
                                                                                         cancelButtonTitle:@"OK"
                                                                                         otherButtonTitles:nil];
                                                  [alert show];
                                              } else {

                                                 //when credit card details is correct code here
                                              }
                                          }];
}

【讨论】:

  • 是的,我们可以检查卡是否是信用卡,但可以对其进行自定义类,如果我们使用的是 stp,那么他们为我们提供了验证方法,我们只需要实现它
  • @FeminaBrahmbhatt,您能否提供代码级指南来检查卡是借记卡还是贷记卡?
  • @AbidHussain 你有没有找到任何方法来检查卡是借记卡还是信用卡?
【解决方案2】:

Swift 2.1 版本的 Femina 的回答。注意: validateCardType() 是一个正则表达式函数,如果你也想要,你可以在这里找到它How do you detect Credit card type based on number?

func validateCustomerInfo() -> Bool {
    // Validate card number, CVC, expMonth, expYear
    STPCardValidator.validationStateForExpirationMonth(self.expMonth.text!)
    STPCardValidator.validationStateForExpirationYear(self.expYear.text!, inMonth: self.expMonth.text!)

    if (self.validateCardType(creditCardField.text!) == "Visa") {
        STPCardValidator.validationStateForCVC(self.securityField.text!, cardBrand: STPCardBrand.Visa)
        STPCardValidator.validationStateForNumber(self.creditCardField.text!, validatingCardBrand: true)
    }
    else if (self.validateCardType(creditCardField.text!) == "MasterCard") {
        STPCardValidator.validationStateForCVC(self.securityField.text!, cardBrand: STPCardBrand.MasterCard)
        STPCardValidator.validationStateForNumber(self.creditCardField.text!, validatingCardBrand: true)
    }
    else if (self.validateCardType(creditCardField.text!) == "American Express") {
        STPCardValidator.validationStateForCVC(self.securityField.text!, cardBrand: STPCardBrand.Amex)
        STPCardValidator.validationStateForNumber(self.creditCardField.text!, validatingCardBrand: true)
    }
    else if (self.validateCardType(creditCardField.text!) == "Discover") {
        STPCardValidator.validationStateForCVC(self.securityField.text!, cardBrand: STPCardBrand.Discover)
        STPCardValidator.validationStateForNumber(self.creditCardField.text!, validatingCardBrand: true)
    }
    else if (self.validateCardType(creditCardField.text!) == "Diners Club") {
        STPCardValidator.validationStateForCVC(self.securityField.text!, cardBrand: STPCardBrand.DinersClub)
        STPCardValidator.validationStateForNumber(self.creditCardField.text!, validatingCardBrand: true)
    }
    else if (self.validateCardType(creditCardField.text!) == "JCB") {
        STPCardValidator.validationStateForCVC(self.securityField.text!, cardBrand: STPCardBrand.JCB)
        STPCardValidator.validationStateForNumber(self.creditCardField.text!, validatingCardBrand: true)
    }
    else if (self.validateCardType(creditCardField.text!) == "Unknown") {
        STPCardValidator.validationStateForCVC(self.securityField.text!, cardBrand: STPCardBrand.Unknown)
        STPCardValidator.validationStateForNumber(self.creditCardField.text!, validatingCardBrand: true)
    }

    return true
}

【讨论】:

    【解决方案3】:

    执行此操作的最简单方法,而不是进行所有计算。

    您可以使用STPCardValidatorvalidationStateForCard 方法,它将STPCardParams 实例作为参数。

    - (IBAction)buyButtonTapped:(id)sender{
    
        param = [[STPCardParams alloc]init];
        param.number = txt_cc_no.text;
        param.cvc = txt_cc_cvvno.text;
        param.expMonth =[self.selectedMonth integerValue];
        param.expYear = [self.selectedYear integerValue];
    
    
       if ([self validateCustomerInfo]) {
           [self performStripeOperation];
       }
    
    }
    
    func validateCustomerInfo() -> Bool {
    
        // Validate card number, CVC, expMonth, expYear
        return STPCardValidator.validationStateForCard(param) == .Valid
    }
    

    【讨论】:

      【解决方案4】:

      对于 Swift 3

          // Validate all params at once
          let cardSate = STPCardValidator.validationState(forCard: cardParams)
          // Validate card number, CVC, expMonth, expYear one by one
          let numberState = STPCardValidator.validationState(forNumber: cardParams.number, validatingCardBrand: true)
          let cvcState = STPCardValidator.validationState(forCVC: cardParams.cvc ?? "", cardBrand: STPCardValidator.brand(forNumber: cardParams.number ?? ""))
          let expMonthState = STPCardValidator.validationState(forExpirationMonth: String(cardParams.expMonth ?? 0))
          let expYearState = STPCardValidator.validationState(forExpirationYear: String(cardParams.expYear ?? 0), inMonth: String(cardParams.expMonth ?? 0))
      

      【讨论】:

        【解决方案5】:

        Swift 5.0+

        别忘了import Stripe

        func isCardDetailValid(cardNumber : String, month : UInt, year : UInt, cvv : String) -> Bool {
            let params = STPCardParams()
            params.number = cardNumber
            params.expMonth = month
            params.expYear = year
            params.cvc = cvv
            if STPCardValidator.validationState(forCard: params) == .valid {
                return true
            } else {
                return false
            }
        }
        

        【讨论】:

          【解决方案6】:

          这是@iOSArchitect.com 的完整且更正确的 Swift 答案

          func paymentCardTextFieldDidChange(_ textField: STPPaymentCardTextField) {
              let isValid = isValidCard(cardNumber: textField.cardNumber, month: textField.expirationMonth, year: textField.expirationYear, cvv: textField.cvc)
          }
          
          func isValidCard(cardNumber: String?, month: UInt, year: UInt, cvv: String?) -> Bool {
              let params = STPCardParams()
              params.number = cardNumber
              params.expMonth = month
              params.expYear = year
              params.cvc = cvv
              if STPCardValidator.validationState(forCard: params) == .valid {
                  return true
              } else {
                  return false
              }
          }
          

          【讨论】:

            猜你喜欢
            • 2015-04-13
            • 2013-01-11
            • 2014-08-14
            • 2021-07-04
            • 1970-01-01
            • 2011-01-24
            • 2012-08-14
            • 2017-04-02
            • 2016-11-15
            相关资源
            最近更新 更多