WDCardField is a field with similar properties to UITextField, but specialized for collecting card data. It manages multiple UITextFields under the hood to collect this data. It's designed to fit on a single line, and from a design perspective can be used anywhere a UITextField would be appropriate.
- Create WDCardField programatically or in XIB/Storyboard and keep reference to instance in your UIViewController 
    1 \@interface PaymentViewController UIViewController<WDCardFieldDelegate>
     3 \@property (nonatomic, weak) IBOutlet WDCardField *cardField;
     4 \@property (nonatomic, weak) IBOutlet UIButton *paymentButton;
     5 \@property (nonatomic, strong) WDClient *client;
  
- Initialize WDCardField with WDCardPayment: 
    1 @implementation PaymentViewController
     4     WDCardPayment *payment = [[WDCardPayment alloc] initWithAmount:[NSDecimalNumber decimalNumberWithMantissa:1275 exponent:-2 isNegative:NO]
     5                                                     amountCurrency:WDCurrencyEUR
     6                                                    transactionType:WDTransactionTypePurchase];
     8     WDCardToken *token = nil;
     9     if (shouldCollectSecurityCodeOnly) {
    10         token = [WDCardToken new];
    11         token.tokenID = @"4585779929881111";
    12         token.maskedAccountNumber = @"444433******1111";
    14         // It is convenient to set the card data if you collect security code only. According card brand security code is validated.
    16         card.brand = WDCardBrandVisa;
    17         card.expiryDate = [NSDate date];
    19     WDCardField *cardField = self.cardField;
    20     cardField.cardPayment = [self buildPaymentWithToken:token];
    21     cardField.card = card;
    22     cardField.delegate = self; // it can be set via XIB as well
    24     // initalize WDClient instance
    25     self.client = [[WDClient alloc] initWithEnvironment:WDEnvironmentTEST];
  
- Implement protocol WDCardFieldDelegate to handle user actions listed in WDCardFieldState : 
    1 #pragma mark - WDCardFieldDelegate
     3 - (void)cardField:(WDCardField *)cardField didChangeState:(WDCardFieldState)state {
     4     // simple data validation
     5     self.paymentButton.enabled = cardField.valid;
     7     // you can improve UX by handling state and showing hints to user
  
- Make the payment 
    1 #pragma mark - Payment Button action
     3 - (IBAction)makePayment:(UIButton *)sender {
     4     WDPayment *payment = self.cardField.cardPayment;
     6     // The data can be created in advance requestTimestamp expiration is 30 mins.
     7     payment.merchantAccountID = merchantAccountID;   // provided by support
     8     payment.requestID = [[NSUUID UUID] UUIDString];  // generated on server unique to merchant
     9     payment.requestTimestamp = [NSDate date];        // generated on server
    10     payment.requestSignature = signature;            // generated on server
    12     // Create block to handle response
    13     WDCompletionBlock completionBlock = ^(WDPaymentResponse *_Nullable response, NSError *_Nullable error) {
    15             WDErrorCode errorCode = error.code;
    22     // Trigger the payment
    23     [self.client makePayment:payment withCompletion:completionBlock];