swift - Populate STPPaymentCardTextField Programma

2019-03-06 05:57发布

问题:

I'm developing an app and using Stripe SDK and Card.io SDK. What i want to happen is populate the STPPaymentCardTextField Card Number,Expiry Month and Year with Card.io scanned credit card value. I Tried:

var paymentField = STPPaymentCardTextField()

func userDidProvideCreditCardInfo(cardInfo: CardIOCreditCardInfo!, inPaymentViewController paymentViewController: CardIOPaymentViewController!) {
    var scanViewController: CardIOPaymentViewController = CardIOPaymentViewController(paymentDelegate: self)
    paymentField.cardNumber = cardInfo.cardNumber
    paymentField.expirationMonth = cardInfo.expiryMonth
    paymentField.expirationYear = cardInfo.expiryYear

    paymentViewController.dismissViewControllerAnimated(true, completion: nil)
}

I'm having an error Cannot assign to the result of this expression for each paymentField append. What do you think i can do with this? Thanks!

回答1:

STPPaymentCardTextField fields are read-only and you can only "get" from those properties.

STPPaymentCardTextField is used to collect credit card details. In your case you are already doing that using CardIOCreditCardInfo. Once you have the credit card details you can assemble the data into an STPCardParams object.

Once you've collected the card number, expiration, and CVC, package them up in an STPCardParams object and invoke the createTokenWithCard: method on the STPAPIClient class.

Now your method may look like this...

func userDidProvideCreditCardInfo(cardInfo: CardIOCreditCardInfo!, inPaymentViewController paymentViewController: CardIOPaymentViewController!) {

        let card: STPCardParams = STPCardParams()
        card.number = info.cardNumber
        card.expMonth = info.expiryMonth
        card.expYear = info.expiryYear
        card.cvc = info.cvv

        STPAPIClient.sharedClient().createTokenWithCard(card, completion: {(result, error) -> Void in
            if error == nil {
                // Either save the card token with your customer data or charge them right away
                //createBackendChargeWithToken(token)
            }
            else {
                //handleError(error)
            }
        })
    }
    paymentViewController?.dismissViewControllerAnimated(true, completion: nil)
}

Update May be the right answer to your question.

import Stripe
class PaymentCardEditorField: STPPaymentCardTextField {
    func setExistingCard(card: STPCardParams) {
        replaceField("numberField", withValue: card.number!)
        replaceField("expirationField", withValue: String(format: "%02d/%02d", card.expMonth, (card.expYear % 100)))
        replaceField("cvcField", withValue: card.cvc!)
    }

    func replaceField(memberName: String, withValue value: String) {
        let field = self.valueForKey(memberName) as! UITextField
        let delegate = self as! UITextFieldDelegate
        let len = field.text?.characters.count
        if delegate.textField?(field, shouldChangeCharactersInRange: NSMakeRange(0, len!), replacementString: value) ?? false {
        field.text = value
        }
    }
}

And then call the setExistingCard

func userDidProvideCreditCardInfo(cardInfo: CardIOCreditCardInfo!, inPaymentViewController paymentViewController: CardIOPaymentViewController!) {

    let card: STPCardParams = STPCardParams()
    card.number = info.cardNumber
    card.expMonth = info.expiryMonth
    card.expYear = info.expiryYear
    card.cvc = info.cvv
    paymentTextField.setExistingCard(card)
}

Works like a charm.

Follow this thread for potential update to Stripe SDK for in built support in the future.

https://github.com/stripe/stripe-ios/issues/127