NAV
docs

Create Token

Apple Pay in Apps

If you want to know the latest SDK version and the difference between each version, please refer to Github Release Page: TapPay iOS Github

Support iOS 10 and later.

Apple Pay works with Safari, Google’s Chrome, Microsoft’s Edge and Mozilla’s Firefox browsers on the iPhone in the fourth beta of iOS 16 and iPadOS 16 or above. Other versions only support on Safari.

Environment

Before you get to coding, make sure you have done the following things:

1. Download and import TPDirect.framework into your project.
2. Import PassKit.framework into your project.
3. Enable Apple Pay in your Xcode and add Apple Merchant IDs.

4. Use TPDSetup to set up your environment.
5. Please open Advertising Identifier, to improve the accuracy of fraud detect.

TPDSetup

+ (instancetype _Nonnull)setWithAppId:(int)appId
                           withAppKey:(NSString *_Nonnull)appKey
                       withServerType:(TPDServerType)serverType;
class func setWithAppKey(_ appKey: String, withAppId appId: Int32, with serverType: TPDServerType) -> Self



...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    [TPDSetup setWithAppId:"APP_ID" withAppKey:@"APP_KEY" withServerType:TPDServer_SandBox];

    return YES;
}

...

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
  // Override point for customization after application launch.
  TPDSetup.setWithAppId("APP_ID", withAppKey: "APP_KEY", with: TPDServerType.sandBox)

  return true
}
Name Type Usage
appID int Application identifier
appKey String Application authorization key
serverType TPDServerType Types of server.
Use Sandbox(TPDServerType.Sandbox) for testing, and switch to Production(TPDServerType.Production) after your product launches.


Please open Advertising Identifier, to improve the accuracy of fraud detect.

Codes

  1. Import PassKit and TPDirect frameworks into your project.
#import <PassKit/PassKit.h>
#import <TPDirect/TPDirect.h>
import PassKit
import TPDirect

2. Implement the following classes in order:

TPDApplePay

@interface ViewController () <TPDApplePayDelegate>

@property (nonatomic, strong) TPDApplePay *applePay;

@end
class ViewController: UIViewController {

    var applePay : TPDApplePay!

}

TPDApplePayDelegate

@protocol TPDApplePayDelegate <NSObject>

@required
// Send To The Delegate After Receive Prime and prime expiry millis.
- (void)tpdApplePay:(TPDApplePay *)applePay didReceivePrime:(NSString *)prime withExpiryMillis:(long)expiryMillis withCardInfo:(TPDCardInfo *)cardInfo withMerchantReferenceInfo:(NSDictionary *)merchantReferenceInfo;

// Send To The Delegate After Apple Pay Payment Processing Succeeds.
- (void)tpdApplePay:(TPDApplePay *)applePay didSuccessPayment: (TPDTransactionResult *)result;

// Send To The Delegate After Apple Pay Payment Processing Fails.
- (void)tpdApplePay:(TPDApplePay *)applePay didFailurePayment: (TPDTransactionResult *)result;

@optional
// Send To The Delegate After Apple Pay Payment's Form Is Shown.
- (void)tpdApplePayDidStartPayment:(TPDApplePay *)applePay;

// Send To The Delegate After User Selects A Payment Method.
// You Can Change The PaymentItem Or Discount Here.
- (TPDCart *)tpdApplePay:(TPDApplePay *)applePay didSelectPaymentMethod: (PKPaymentMethod *)paymentMethod cart:(TPDCart *)cart;

// Send To The Delegate After User Selects A Shipping Method.
// Set shippingMethods ==> TPDMerchant.shippingMethods.
- (void)tpdApplePay:(TPDApplePay *)applePay didSelectShippingMethod: (PKShippingMethod *)shippingMethod;

// Send To The Delegate After User Authorizes The Payment.
// You Can Check Shipping Contact Here, Return YES If Authorized.
- (BOOL)tpdApplePay:(TPDApplePay *)applePay canAuthorizePaymentWithShippingContact:(PKContact *)shippingContact;

// Send To The Delegate After User Cancels The Payment.
- (void)tpdApplePayDidCancelPayment:(TPDApplePay *)applePay;

// Send To The Delegate After Apple Pay Payment's Form Disappeared.
- (void)tpdApplePayDidFinishPayment:(TPDApplePay *)applePay;

@end
public protocol TPDApplePayDelegate : NSObjectProtocol {
  // Send To The Delegate After Receive Prime.
  public func tpdApplePay(_ applePay: TPDApplePay!, didReceivePrime prime: String!, withExpiryMillis expiryMillis: Int, withCardInfo cardInfo: TPDCardInfo, withMerchantReferenceInfo merchantReferenceInfo: [AnyHashable : Any]!)

  // Send To The Delegate After Apple Pay Payment Processing Succeeds.
  public func tpdApplePay(_ applePay: TPDApplePay!, didSuccessPayment result: TPDTransactionResult!)

  // Send To The Delegate After Apple Pay Payment Processing Fails.
  public func tpdApplePay(_ applePay: TPDApplePay!, didFailurePayment result: TPDTransactionResult!)

  // Send To The Delegate After Apple Pay Payment's Form Is Shown.
  optional public func tpdApplePayDidStartPayment(_ applePay: TPDApplePay!)

  // Send To The Delegate After User Selects A Payment Method.
  // You Can Change The PaymentItem Or Discount Here.
  @available(iOS 9.0, *)
  optional public func tpdApplePay(_ applePay: TPDApplePay!, didSelect paymentMethod: PKPaymentMethod!, cart: TPDCart!) -> TPDCart!

  // Send To The Delegate After User Selects A Shipping Method.
  // Set shippingMethods ==> TPDMerchant.shippingMethods.
  @available(iOS 8.0, *)
  optional public func tpdApplePay(_ applePay: TPDApplePay!, didSelect shippingMethod: PKShippingMethod!)

  // Send To The Delegate After User Authorizes The Payment.
  // You Can Check Shipping Contact Here, Return YES If Authorized.
  @available(iOS 9.0, *)
  optional public func tpdApplePay(_ applePay: TPDApplePay!, canAuthorizePaymentWithShippingContact shippingContact: PKContact!) -> Bool

  // Send To The Delegate After User Cancels The Payment.
  optional public func tpdApplePayDidCancelPayment(_ applePay: TPDApplePay!)

  // Send To The Delegate After Apple Pay Payment's Form Disappeared.
  optional public func tpdApplePayDidFinishPayment(_ applePay: TPDApplePay!)
}
Name Usage
didSuccessPayment Called when a successful payment has been made.
didFailurePayment Called when the payment failed.
tpdApplePayDidStartPayment Called when the payment begins.
didSelectPaymentMethod Called when a payment method is selected.
didSelectShippingMethod Called when a shipping method is selected.
canAuthorizePaymentWithShippingContact Check if the payment can be authorized with the given shipping contact.
tpdApplePayDidCancelPayment Called when the payment is cancelled.
tpdApplePayDidFinishPayment Called when the payment is finished, but before the result has been determined.
didReceivePrime:withExpiryMillis:withCardInfo:withMerchantReferenceInfo Called when you obtained the Prime and expiry millis from TapPay.
You should pass this token back to your server, and call our Pay by Prime API to finish the transaction.
Afterwards, call “showPaymentResult” to display the result.
showPaymentResult Called after you finished the payment process on your server with Pay by Prime API.

TPDTransactionResult

  @interface TPDTransactionResult : NSObject
  // message, Report Message.
  @property (nonatomic, strong) NSString *message;

  // status, Result Code, '0' Means Success.
  @property (nonatomic, assign) NSInteger status;

  // amount
  @property (nonatomic, strong) NSDecimalNumber *amount;

  // paymentMehod
  @property (nonatomic, strong) PKPaymentMethod *paymentMethod;
  @end
class TPDTransactionResult : NSObject {
  // message, Report Message.
  var message: String!

  // status, Result Code, '0' Means Success.
  var status: Int

  // amount
  var amount: NSDecimalNumber!

  // paymentMehod
  var paymentMethod: PKPaymentMethod!
}

The returned object in didSuccessPayment and didFailurePayment, TPDTransactionResult, will contain the following values:

Name Usage
amount Amount for the transaction.
status Status code for the transaction.
message Error message for the transaction.
paymentMehod Apple’s PKPaymentMethod
- (void)tpdApplePayDidStartPayment:(TPDApplePay *)applePay {
  NSLog(@"=====================================================");
  NSLog(@"Apple Pay On Start");
  NSLog(@"===================================================== \n\n");
}

- (void)tpdApplePay:(TPDApplePay *)applePay didSuccessPayment: (TPDTransactionResult *)result {
  NSLog(@"=====================================================");
  NSLog(@"Apple Pay Did Success ==> Amount : %@", [result.amount stringValue]);
  NSLog(@"shippingContact.name : %@ %@", applePay.consumer.shippingContact.name.givenName, applePay.consumer.shippingContact.name.familyName);
  NSLog(@"shippingContact.emailAddress : %@", applePay.consumer.shippingContact.emailAddress);
  NSLog(@"shippingContact.phoneNumber : %@", applePay.consumer.shippingContact.phoneNumber.stringValue);
  NSLog(@"===================================================== \n\n");
}

- (void)tpdApplePay:(TPDApplePay *)applePay didFailurePayment: (TPDTransactionResult *)result {
  NSLog(@"=====================================================");
  NSLog(@"Apple Pay Did Failure ==> Message : %@, ErrorCode : %ld", result.message, (long)result.status);
  NSLog(@"===================================================== \n\n");
}

- (void)tpdApplePayDidCancelPayment:(TPDApplePay *)applePay {
  NSLog(@"=====================================================");
  NSLog(@"Apple Pay Did Cancel");
  NSLog(@"===================================================== \n\n");
}

- (void)tpdApplePayDidFinishPayment:(TPDApplePay *)applePay {
  NSLog(@"=====================================================");
  NSLog(@"Apple Pay Did Finish");
  NSLog(@"===================================================== \n\n");
}

- (void)tpdApplePay:(TPDApplePay *)applePay didSelectShippingMethod: (PKShippingMethod *)shippingMethod {
  NSLog(@"=====================================================");
  NSLog(@"======> didSelectShippingMethod: ");
  NSLog(@"Shipping Method.identifier : %@", shippingMethod.identifier);
  NSLog(@"Shipping Method.detail : %@", shippingMethod.detail);
  NSLog(@"===================================================== \n\n");
}

- (TPDCart *)tpdApplePay:(TPDApplePay *)applePay didSelectPaymentMethod: (PKPaymentMethod *)paymentMethod cart:(TPDCart *)cart {
  NSLog(@"=====================================================");
  NSLog(@"======> didSelectPaymentMethod: ");
  NSLog(@"===================================================== \n\n");
  if (paymentMethod.type == PKPaymentMethodTypeDebit) {
    [self.cart addPaymentItem:[TPDPaymentItem paymentItemWithItemName:@"Discount"
                                                           withAmount:[NSDecimalNumber decimalNumberWithString:@"-1.00"]]];
  }
  return self.cart;
}

- (BOOL)tpdApplePay:(TPDApplePay *)applePay canAuthorizePaymentWithShippingContact:(PKContact *)shippingContact {
  NSLog(@"=====================================================");
  NSLog(@"======> canAuthorizePaymentWithShippingContact ");
  NSLog(@"shippingContact.name : %@ %@", applePay.consumer.shippingContact.name.givenName, applePay.consumer.shippingContact.name.familyName);
  NSLog(@"shippingContact.emailAddress : %@", shippingContact.emailAddress);
  NSLog(@"shippingContact.phoneNumber : %@", shippingContact.phoneNumber.stringValue);
  NSLog(@"===================================================== \n\n");
  return YES;
}

- (void)tpdApplePay:(TPDApplePay *)applePay didReceivePrime:(NSString *)prime withExpiryMillis:(long)expiryMillis withCardInfo:(TPDCardInfo *)cardInfo withMerchantReferenceInfo:(NSDictionary *)merchantReferenceInfo {

  // 1. Send Your 'Prime' To Your Server, And Handle Payment With Result
  // ...
  NSLog(@"=====================================================");
  NSLog(@"======> didReceivePrime ");
  NSLog(@"Prime : %@", prime);
  NSLog(@"apple pay %lu", expiryMillis);
  NSLog(@"totalAmount : %@",applePay.cart.totalAmount);
  NSLog(@"Client  IP : %@",applePay.consumer.clientIP);
  NSLog(@"shippingContact.name : %@ %@", applePay.consumer.shippingContact.name.givenName, applePay.consumer.shippingContact.name.familyName);
  NSLog(@"shippingContact.emailAddress : %@", applePay.consumer.shippingContact.emailAddress);
  NSLog(@"shippingContact.phoneNumber : %@", applePay.consumer.shippingContact.phoneNumber.stringValue);
  PKPaymentMethod * paymentMethod = applePay.consumer.paymentMethod;
  NSLog(@"Type : %ld", (long)paymentMethod.type);
  NSLog(@"Network : %@", paymentMethod.network);
  NSLog(@"Display Name : %@", paymentMethod.displayName);
  NSLog(@"===================================================== \n\n");

  // 2. If Payment Success, applePay.
  BOOL paymentResult = YES;
  [applePay showPaymentResult:paymentResult];   
}
extension ViewController :TPDApplePayDelegate {

  func tpdApplePayDidStartPayment(_ applePay: TPDApplePay!) {
    print("=====================================================")
    print("Apple Pay On Start")
    print("=====================================================\n\n")
  }

  func tpdApplePay(_ applePay: TPDApplePay!, didSuccessPayment result: TPDTransactionResult!) {
    print("=====================================================")
    print("Apple Pay Did Success ==> Amount : \(result.amount.stringValue)")
    print("shippingContact.name : \(applePay.consumer.shippingContact?.name?.givenName) \( applePay.consumer.shippingContact?.name?.familyName)")
    print("shippingContact.emailAddress : \(applePay.consumer.shippingContact?.emailAddress)")
    print("shippingContact.phoneNumber : \(applePay.consumer.shippingContact?.phoneNumber?.stringValue)")
    print("Shipping Method.identifier : \(applePay.cart.shippingMethod.identifier)")
    print("Shipping Method.detail : \(applePay.cart.shippingMethod.detail)")
    print("=====================================================\n\n")
  }

  func tpdApplePay(_ applePay: TPDApplePay!, didFailurePayment result: TPDTransactionResult!) {
    print("=====================================================")
    print("Apple Pay Did Failure ==> Message : \(result.message), ErrorCode : \(result.status)")
    print("=====================================================\n\n")
  }

  func tpdApplePayDidCancelPayment(_ applePay: TPDApplePay!) {
    print("=====================================================")
    print("Apple Pay Did Cancel")
    print("=====================================================\n\n")
  }

  func tpdApplePayDidFinishPayment(_ applePay: TPDApplePay!) {
    print("=====================================================")
    print("Apple Pay Did Finish")
    print("=====================================================\n\n")
  }

  func tpdApplePay(_ applePay: TPDApplePay!, didSelect shippingMethod: PKShippingMethod!) {
    print("=====================================================")
    print("======> didSelectShippingMethod: ")
    print("Shipping Method.identifier : \(shippingMethod.identifier)")
    print("Shipping Method.detail : \(shippingMethod.detail)")
    print("=====================================================\n\n")
  }

  func tpdApplePay(_ applePay: TPDApplePay!, didSelect paymentMethod: PKPaymentMethod!, cart: TPDCart!) -> TPDCart! {
    print("=====================================================");
    print("======> didSelectPaymentMethod: ");
    print("=====================================================\n\n");
    if paymentMethod.type == .debit {
      self.cart.add(TPDPaymentItem(itemName: "Discount", withAmount: NSDecimalNumber(string: "-1.00")))
    }
    return self.cart;
  }

  func tpdApplePay(_ applePay: TPDApplePay!, canAuthorizePaymentWithShippingContact shippingContact: PKContact!) -> Bool {
    print("=====================================================")
    print("======> canAuthorizePaymentWithShippingContact ")
    print("shippingContact.name : \(applePay.consumer.shippingContact?.name?.givenName) \( applePay.consumer.shippingContact?.name?.familyName)")
    print("shippingContact.emailAddress : \(shippingContact.emailAddress)")
    print("shippingContact.phoneNumber : \(shippingContact.phoneNumber?.stringValue)")
    print("=====================================================\n\n")
    return true;
  }

  tpdApplePay(_ applePay: TPDApplePay!, didReceivePrime prime: String!, withExpiryMillis expiryMillis: Int, withCardInfo cardInfo: TPDCardInfo, withMerchantReferenceInfo merchantReferenceInfo: [AnyHashable : Any]!) {

    // 1. Send Your Prime To Your Server, And Handle Payment With Result
    // ...
    print("=====================================================");
    print("======> didReceivePrime");
    print("Prime : \(prime!)");
    print("Expiry Millis : \(expiryMillis)");
    print("total Amount :   \(applePay.cart.totalAmount!)")
    print("Client IP : \(applePay.consumer.clientIP!)")
    print("shippingContact.name : \(applePay.consumer.shippingContact?.name?.givenName) \(applePay.consumer.shippingContact?.name?.familyName)");
    print("shippingContact.emailAddress : \(applePay.consumer.shippingContact?.emailAddress)");
    print("shippingContact.phoneNumber : \(applePay.consumer.shippingContact?.phoneNumber?.stringValue)");
    let paymentMethod = self.consumer.paymentMethod!        
    print("type : \(paymentMethod.type.rawValue)")
    print("Network : \(paymentMethod.network!.rawValue)")
    print("Display Name : \(paymentMethod.displayName!)")
    print("===================================================== \n\n");

    // 2. If Payment Success, applePay.
    let paymentResult = true;
    applePay.showPaymentResult(paymentResult)
    }
}


Name Type Content
prime String prime token used in Pay by Prime
expiryMillis Int prime expired millis
cardInfo TPDCardInfo Card information:
NameType(Max)Usage
bincodeString(6)First six digits of the card
lastFourString(4)Last four digits of the card
issuerStringCard issuer
issuerZhTwStringCard issuer chinese name
bankIdStringBank identifier
fundingint Card usage
-1 = Unknown
0 = credit card
1 = debit card
2 = prepaid card
cardTypeintCard type
-1 = Unknown
1 = VISA
2 = MasterCard
3 = JCB
4 = Union Pay
5 = AMEX
levelStringCard level
countryStringCountry of card issuer
countryCodeStringCountry code of card issuer
merchantReferenceInfo JSONObject If the merchant uses the co-branded card management in the TapPay portal, and the transaction card number meets the setting, this parameter will be returned.

Set in TapPay Portal, must limit 20 character and half alphanumeric.
Not support : JKOPAY
NameTypeContent
affiliateCodesArrayAffiliated codes set by the merchant in the Co-brand card management area of ​​the TapPay portal.

PKPaymentButton

@interface ViewController () <TPDApplePayDelegate>

@property (nonatomic, strong) PKPaymentButton *applePayButton;

@end
class ViewController: UIViewController {

    var applePayButton : PKPaymentButton!

}

You should check if the card or the device supports Apple Pay before setting up the payment button.

/**
[TPDApplePay canMakePaymentsUsingNetworks:(NSArray<PKPaymentNetwork> *)]
  Check support cart network.

  TPDApplePay setupWthMerchant:(TPDMerchant *) withConsumer:(TPDConsumer *) withCart:(TPDCart *) withDelegate:(id)
  Use TPDMerchant, TPDConsumer, TPDCart to initial Apple Pay Instance.

  startPayment
  Start Apple Pay Payment Sheet
*/

- (void)paymentButtonSetting {

    // Check if the card can use Apple Pay.
    if ([TPDApplePay canMakePaymentsUsingNetworks:self.merchant.supportedNetworks]) {
        self.applePayButton = [PKPaymentButton buttonWithType:PKPaymentButtonTypeBuy style:PKPaymentButtonStyleBlack];
    }else{
        self.applePayButton = [PKPaymentButton buttonWithType:PKPaymentButtonTypeSetUp style:PKPaymentButtonStyleBlack];
    }

    [self.view addSubview:self.applePayButton];
    self.applePayButton.center = self.view.center;

    [self.applePayButton addTarget:self action:@selector(didClickButton:) forControlEvents:UIControlEventTouchUpInside];
}

- (void)didClickButton:(PKPaymentButton *)sender {

    self.applePay = [TPDApplePay setupWthMerchant:self.merchant withConsumer:self.consumer withCart:self.cart withDelegate:self];

    [self.applePay startPayment];
}
/**
  TPDApplePay.canMakePayments(usingNetworks: [PKPaymentNetwork]!)
  Check support cart network.

  TPDApplePay.setupWthMerchant(TPDMerchant!, with: TPDConsumer!, with: TPDCart!, withDelegate: Any!)
  Use TPDMerchant, TPDConsumer, TPDCart to initial Apple Pay Instance.

  startPayment
  Start Apple Pay Payment Sheet
*/

func paymentButtonSetting() {

    // Check if the card can use Apple Pay.
    if (TPDApplePay.canMakePayments(usingNetworks: self.merchant.supportedNetworks)) {
        applePayButton = PKPaymentButton.init(paymentButtonType: .buy, paymentButtonStyle: .black)
    } else {
        applePayButton = PKPaymentButton.init(paymentButtonType: .setUp, paymentButtonStyle: .black)
    }

    view.addSubview(applePayButton)
    applePayButton.center = view.center

    applePayButton.addTarget(self, action: #selector(ViewController.didClickBuyButton(sender:)), for: .touchUpInside)

}

@objc func didClickBuyButton(sender:PKPaymentButton) {

    applePay = TPDApplePay.setupWthMerchant(merchant, with: consumer, with: cart, withDelegate: self)

    applePay.startPayment()

}

TPDMerchant

@interface ViewController () <TPDApplePayDelegate>

@property (nonatomic, strong) TPDMerchant *merchant;

@end
class ViewController: UIViewController {

    var merchant : TPDMerchant!

}


self.merchant = [TPDMerchant new];
self.merchant.merchantName               = @"TapPay!";
self.merchant.merchantCapability         = PKMerchantCapability3DS;
self.merchant.applePayMerchantIdentifier = @"merchant.apple.pay";       
self.merchant.countryCode                = @"TW";
self.merchant.currencyCode               = @"TWD";
self.merchant.supportedNetworks          = @[PKPaymentNetworkAmex, PKPaymentNetworkMasterCard, PKPaymentNetworkVisa, PKPaymentNetworkJCB];
merchant = TPDMerchant()
merchant.merchantName               = "TapPay!";
merchant.merchantCapability         = .capability3DS;
merchant.applePayMerchantIdentifier = "merchant.apple.pay";
merchant.countryCode                = "TW";
merchant.currencyCode               = "TWD";
merchant.supportedNetworks          = [.amex, .masterCard, .visa, .JCB]


Name Values
merchantName Display merchant name on Payment Sheet.
merchantCapability The payment capabilities supported by the merchant, please refer to Apple Pay merchantCapabilities
applePayMerchantIdentifier The Apple Merchant ID.
countryCode The abbreviation code for the country following the ISO 3166-1 alpha-2 format.
currencyCode The abbreviation code for the country currency following the ISO 4217 format.
supportedNetworks Set the credit card network you want to support


supportedNetworks card network supported version

Card network Version
American Express iOS 8.0+
watchOS 3.0+
MasterCard iOS 8.0+
watchOS 3.0+
Visa iOS 8.0+
watchOS 3.0+
JCB iOS 10.1+
watchOS 3.1+

TPDConsumer

@interface ViewController () <TPDApplePayDelegate>

@property (nonatomic, strong) TPDConsumer *consumer;

@end
class ViewController: UIViewController {

    var consumer : TPDConsumer!

}


self.consumer = [TPDConsumer new];
self.consumer.requiredShippingAddressFields  = PKAddressFieldEmail | PKAddressFieldName | PKAddressFieldPhone;
self.consumer.requiredBillingAddressFields   = PKAddressFieldPostalAddress;
consumer = TPDConsumer()
consumer.requiredShippingAddressFields  = [.email, .name, .phone]
consumer.requiredBillingAddressFields   = [.postalAddress]


Name Content
requiredShippingAddressFields Required shipping address information field.
Default no fields required.
requiredBillingAddressFields Required billing address information field.
Default no fields required.


After the Apple Pay authentication is successful, you can get the card information in the didReceivePrime delegate, TPDConsumer.paymentMethod
More info refer to apple pay docs PKPaymentMethod

Name Content
type Card type
0 : unknown
1 : debit
2 : credit
3 : prepaid
4 : store
network Card network
displayName Card network and card last four number

TPDCart

@interface ViewController () <TPDApplePayDelegate>

@property (nonatomic, strong) TPDCart *cart;

@end
class ViewController: UIViewController {

    var cart     : TPDCart!

}


/**
  [cart addPaymentItem:(TPDPaymentItem *)]
  Add payment item to item list.
*/

self.cart = [TPDCart new];

TPDPaymentItem *book = [TPDPaymentItem paymentItemWithItemName:@"Book"
                                                    withAmount:[NSDecimalNumber decimalNumberWithString:@"100.00"]];
[self.cart addPaymentItem:book];

self.cart.shippingType   = PKShippingTypeShipping;
/**
  cart.add(TPDPaymentItem!)
  Add payment item to item list.
*/

cart = TPDCart()

let book = TPDPaymentItem(itemName:"Book",
                        withAmount: NSDecimalNumber(string: "100.00"))
cart.add(book)

cart.shippingType   = .shipping;


You can use TPDPaymentItem to add new items to TPDCart.
Use paymentItemWithItemName to set up to display the amount of items.
The sum of amount of items in TPDCart must be greater than zero, otherwise the program will return error code: 88016

Deferred Payment

self.cart = [TPDCart new];
self.cart.isAmountPending = YES;
self.cart.isShowTotalamount = NO;

TPDPaymentItem *initialCharge = [TPDPaymentItem paymentItemWithItemName:@"Initial Charge"
                                                        withAmount:[NSDecimalNumber decimalNumberWithString:@"100.00"]];
[self.cart addPaymentItem:initialCharge];


TPDPaymentItem *improvementSurcharge  = [TPDPaymentItem pendingPaymentItemWithItemName:@"NT$5 per miles"];
[self.cart addPaymentItem:improvementSurcharge];
cart = TPDCart()
cart.isAmountPending = true
cart.isShowTotalAmount = false

let initialCharge = TPDPaymentItem(itemName: "Initial Charge", withAmount: NSDecimalNumber(string: "100.00"))
cart.add(initialCharge)

let improvementSurcharge = TPDPaymentItem.pendingPaymentItem(withItemName: "NT$5 per miles")
cart.add(improvementSurcharge)


Please contact TapPay Customer Service (support@cherri.tech) to activate Apple Pay deferred payment.
Once the function has been activated, the prime could live for 30 days and payment amount is set by Pay by Prime, not by SDK.
The property isAmountPending of TPDCart could determine whether this transaction enables deferred payment or not. Default is false
The property isShowTotalAmount of TPDCart could determine that total amount of the payment sheet shows the sum of each payment item’s amount or AMOUNT PENDING. Default is false
If the property pendingPaymentItemWithItemName has been set in TPDCart, the payment item’s amount of the payment sheet will show 『...』, which means actual payment amount is unknown.

Use deferred payment, please note the following rules

All items in TPDCart have specific amount.

isAmountPending isShowTotalAmount Total field Prime expire time
true true Display Total Amount 30days
true false Display Amount Pending 30days
false true Display Total Amount 90sec
false false Not Support, refer to error code: 88013 X


All items in TPDCart are amount pending.

isAmountPending isShowTotalAmount Total field Prime expire time
true true Not Support, refer to error code:88014 X
true false Display Amount Pending 30days
false true Not Support, refer to error code: 88015 X
false false Not Support, refer to error code: 88013 X


The items in TPDCart have specific amount and amount pending.

isAmountPending isShowTotalAmount Total field Prime expire time
true true Display Total Amount 30days
true false Display Amount Pending 30days
false true Not Support, refer to error code: 88015 X
false false Not Support, refer to error code: 88013 X


Notice
Due to total amount should be set above 0 in iOS 12 and version lower.
For compatibility, iOS SDK v2.6.0 and version higher will set total amount of 1 to Apple Pay in following situation.

  1. The items of TPDCart are amount pending items and total amount is set to show 『AMOUNT PENDING』(self.cart.isAmountPending = true).
  2. The total amount of items of TPDCart is 0 and total amount is set to show 『AMOUNT PENDING』(self.cart.isAmountPending = true)

Example

If you have any questions, please refer our Apple Pay Example

Apple Pay on the Web

If you want to know the latest SDK version and the difference between each version, please refer to Github Release Page: TapPay Web Github

Apple Pay JavaScript API is only available on iOS device running iOS 10 or later or Mac running macOS Sierra (10.12) or later.

If you enable Apple Pay on the Web Merchant Application Service, please fill in merchant identifier which generated by TapPay (You can find it from Portal > Payment Methods > Apple Pay On The Web)

Requirements

In Apple Pay on the Web, you must meet the following requirements:

1. All pages that include Apple Pay must be served over HTTPS , In production and sandbox. In develop enviroment you can use ngrok to set up an SSH tunnel , you can refer to our Ngrok tutorial
2. Your domain must have a valid SSL certificate.
3. Your server must support the Transport Layer Security (TLS) 1.2 protocol and one of the cipher suites listed below:

Cipher Suite Value Description
0x13, 0x01 TLS_AES_128_GCM_SHA256
0x13, 0x02 TLS_AES_256_GCM_SHA384
0xC0, 0x2B ECDHE-ECDSA-AES128-GCM-SHA256
0xC0, 0x2F ECDHE-RSA-AES128-GCM-SHA256
0xC0, 0x2C ECDHE-ECDSA-AES256-GCM-SHA384
0xC0, 0x30 ECDHE-RSA-AES256-GCM-SHA384

4. Your server must allow access over HTTPS (TCP over port 443) to the Apple Pay IP Addresses provided below:

IP Name Type
17.171.85.7 apple-pay-gateway-cert.apple.com Sandbox
17.171.78.7 apple-pay-gateway-nc-pod1.apple.com Production
17.171.78.71 apple-pay-gateway-nc-pod2.apple.com Production
17.171.78.135 apple-pay-gateway-nc-pod3.apple.com Production
17.171.78.199 apple-pay-gateway-nc-pod4.apple.com Production
17.171.79.12 apple-pay-gateway-nc-pod5.apple.com Production
17.141.128.7 apple-pay-gateway-pr-pod1.apple.com Production
17.141.128.71 apple-pay-gateway-pr-pod2.apple.com Production
17.141.128.135 apple-pay-gateway-pr-pod3.apple.com Production
17.141.128.199 apple-pay-gateway-pr-pod4.apple.com Production
17.141.129.12 apple-pay-gateway-pr-pod5.apple.com Production
17.171.78.9 apple-pay-gateway-nc-pod1-dr.apple.com Production
17.171.78.73 apple-pay-gateway-nc-pod2-dr.apple.com Production
17.171.78.137 apple-pay-gateway-nc-pod3-dr.apple.com Production
17.171.78.201 apple-pay-gateway-nc-pod4-dr.apple.com Production
17.171.79.13 apple-pay-gateway-nc-pod5-dr.apple.com Production
17.141.128.9 apple-pay-gateway-pr-pod1-dr.apple.com Production
17.141.128.73 apple-pay-gateway-pr-pod2-dr.apple.com Production
17.141.128.137 apple-pay-gateway-pr-pod3-dr.apple.com Production
17.141.128.201 apple-pay-gateway-pr-pod4-dr.apple.com Production
17.141.129.13 apple-pay-gateway-pr-pod5-dr.apple.com Production

SetupSDK

Please use following html code to setup payment environment.


Please be aware of the differences of each Web SDK version to avoid loading errors.
https://js.tappaysdk.com/sdk/tpdirect/v5.14.0
https://js.tappaysdk.com/tpdirect/v5.13.1
Please refer to the following usage examples.

<!-- 
    Use TPDirect.setupSDK(appID, appKey, serverType)
    to setup APP ID, App Key, Server Type parameters
-->

<script src="https://js.tappaysdk.com/sdk/tpdirect/v5.14.0"></script>
<script>
    TPDirect.setupSDK(APP_ID, 'APP_KEY', 'sandbox')
</script>



When use web SDK version less than v5.14.0, please use the following path to include the web SDK

<script src="https://js.tappaysdk.com/tpdirect/v5.13.1"></script>
<script>
    TPDirect.setupSDK(APP_ID, 'APP_KEY', 'sandbox')
</script>


Name Usage
appID Please refer to appid
appKey Please refer to appkey
serverType Use ‘sandbox’ for sandbox environment.
Use 'production’ for production environment.



To ensure the security of external resources using Subresource Integrity (SRI), please refer to the following usage example.

<script src="https://js.tappaysdk.com/sdk/tpdirect/<version>" type="text/javascript" 
integrity="sha256-<hash_key>" crossorigin="anonymous"></script>


The hash key for each version can be found in the Release Notes.

checkAvailability()

Check if PaymentRequestAPI is available.

/**
    Use TPDirect.paymentRequestApi.checkAvailability() to detect user's browser
    whether is available to use Payment Request API or not.
*/

TPDirect.paymentRequestApi.checkAvailability()

Setup Apple Pay

/**
    Use TPDirect.paymentRequestApi.setupApplePay to setup parameters about Apple Pay.
*/

TPDirect.paymentRequestApi.setupApplePay({
    merchantIdentifier: 'merchant.tech.cherri',
    countryCode: 'TW'
})


Name (*=required) Type Content
merchantIdentifier* String You registed in Apple Developer Merchant Id
If you enable Apple Pay on the Web Merchant Application Service, please fill in merchantIdentifier which generated by TapPay (You can find it from Portal > Payment Methods > Apple Pay > Apple Pay on the Web)
countryCode String countryCode , default is TW

PaymentRequest

Create a paymentRequest object setup transaction info to retrieve the Prime.

var paymentRequest = {
    supportedNetworks: ['AMEX', 'JCB', 'MASTERCARD', 'VISA'],
    supportedMethods: ['apple_pay'],
    displayItems: [{
        label: 'TapPay - iPhone8',
        amount: { 
            currency: 'TWD', 
            value: '1.00' 
        }
    }],
    total: {
        label: '總金額',
        amount: { 
            currency: 'TWD', 
            value : '1.00' 
        }
    },
    shippingOptions: [{
            id: "standard",
            label: "🚛 Ground Shipping (2 days)",
            detail: 'Estimated delivery time: 2 days',
            amount: {
                currency: "TWD",
                value: "5.00"
            }
        },
        {
            id: "drone",
            label: "🚀 Drone Express (2 hours)",
            detail: 'Estimated delivery time: 2 hours',
            amount: {
                currency: "TWD",
                value: "25.00"
            }
        }
    ],
    options: {
      requestPayerEmail: true,
      requestPayerName: true,
      requestPayerPhone: true,
      requestShipping: true,
      shippingType: 'shipping'
    }
}
Name Type Content
supportedNetworks Array Setup supported networks. Support parameters “VISA"、"MASTERCARD"、"JCB” and “AMEX”.
supportedMethods Array Setup supported methods
displayItems Array
NameTypeContent
labelStringItem Name
amountJSONObjectvalue: item amount
currency: item currency
isAmountPendingBooleanWhether to use apple pay deferred payment, default is false.
If isAmountPending is true,transaction amount will show “Amount Pending”.
You can only choose isAmountPending or amount.value for the same item
More detail please refer to Deferred Payment
total JSONObject
NameTypeContent
labelStringTransaction Summary
amountJSONObjectvalue: total amount
currency: currency
isAmountPendingBooleanWhether to use apple pay deferred payment, and default is false.
More detail please refer to
isShowTotalAmountBooleanApple Pay total field display amount or AMOUNT PENDING, default is true
You can only choose isAmountPending or amount.value for the same item
More detail please refer to Deferred Payment
shippingOptions JSONObject
NameTypeContent
idStringShipping Name
labelStringShipping type description
detailStringShipping detail description (Apple Pay Only)
amountJSONObjectvalue: Shipping amount
currency: Shipping currency
options JSONObject
NameTypeContent
requestPayerEmailBoolRequest Payer Email
requestPayerNameBoolRequest Payer Name
requestPayerPhoneBoolRequest Payer Phone
requestShippingBoolRequest Payer Shipping address
shippingTypeStringShipping type , If you want to setup please refer to shippingType
shipping , delivery , pickup



After you setup payment request object, please use following method to setup Payment Request API

/**
    Use TPDirect.paymentRequestApi.setupPaymentRequest to setup payment requset object
    and return object which decide the user's browser support Payment Request API
    and the user have the card to make payments or not in callback function
*/

TPDirect.paymentRequestApi.setupPaymentRequest(paymentRequest, function (result) {
    if (!result.browserSupportPaymentRequest) {
        console.log('Browser not support PaymentRequest')
        return
    }
    if (result.canMakePaymentWithActiveCard === true) {
        console.log('Current device have supported card')
    } else {
        console.log('Current device without supported card to make payment')
    }
})


setupPaymentRequest have a callback function, callback function have following object properties.

Name Type Content
result JSONObject
NameTypeContent
browserSupportPaymentRequestBooleanDoes Browser support Payment Request API
true: Support
false: Not Support
canMakePaymentWithActiveCardBooleanDoes this device have card to make payment
Apple pay only check user have setup card in Apple Pay.
true: The device have supported card
false: The device don’t have supported card


Deferred Payment

Please contact TapPay Customer Service (support@cherri.tech) to activate Apple Pay deferred payment.
Once the function has been activated, the prime could live for 30 days and payment amount is set by Pay by Prime, not by SDK.
The property total.isAmountPending of paymentRequest could determine whether this transaction enables deferred payment or not. Default is false
The property total.isShowTotalAmount of paymentRequest could determine that total amount of the payment sheet shows the sum of each payment item’s amount or AMOUNT PENDING. Default is false
If isAmountPending:true has been set in displayItems of paymentRequest, the payment item’s amount of the payment sheet will show 『...』, which means actual payment amount is unknown.



Use Deferred payments, please note the following rules

All of the displayItems isAmountPending is false.

total.isAmountPending total.isShowTotalAmount Total field Prime expire time
true true Display Total Amount 30days
true false Display Amount Pending 30days
false true Display Total Amount 90sec
false false Not Support X


All of the displayItems isAmountPending is true.

total.isAmountPending total.isShowTotalAmount Total field Prime expire time
true true Not Support X
true false Display Amount Pending 30days
false true Not Support X
false false Not Support X


All of the displayItems isAmountPending have both.

total.isAmountPending total.isShowTotalAmount Total field Prime expire time
true true Display Total Amount 30days
true false Display Amount Pending 30days
false true Not Support X
false false Not Support X


Notice
Due to total amount should be set above 0 in MacOS 10.14.1, iOS 12.1 and version lower.
For compatibility, Web SDK v5.4.0 and version higher will set total.amount.value:1 to Apple Pay in following situation.

  1. isAmountPending:true has been set in all displayItems of paymentRequest and total amount is set to show 『AMOUNT PENDING』(total.isShowTotalAmount:false)
  2. The total of displayItems’ amount is 0 and total amount is set to show 『AMOUNT PENDING』(total.isShowTotalAmount:false)
  3. There is no items in displayItems and total amount is set to show『AMOUNT PENDING』(total.isShowTotalAmount:false)

Besides, if you pay on Mac, but verify by fingerprint or face ID through iPhone, total amount of the payment sheet will show 1.

shippingOptions

In paymentRequest ShippingOption without detail.

shippingOptions: [{
    id: "standard",
    label: "🚛 Ground Shipping (2 days)",
    amount: {
        currency: "TWD",
        value: "5.00"
    }
}]




In paymentRequest ShippingOption add detail.

shippingOptions: [{
    id: "standard",
    label: "🚛 Ground Shipping (2 days)",
    // apple pay only
    detail: "Estimated delivery time: 2 days",
    amount: {
        currency: "TWD",
        value: "5.00"
    }
}]


Get Prime

/**
    Use TPDirect.paymentRequestApi.getPrime to get prime from TapPay.
*/

TPDirect.paymentRequestApi.getPrime(function(result) {
    console.log('paymentRequestApi.getPrime result', result)
    if (result.status !== 0) {
        console.error('getPrime failed: ' + result.msg)
        return
    }
    var prime = result.prime
})

Get Prime Result

Get the result and send the Prime back to your server to finish the transaction by calling Pay by Prime API.

{
    "prime": String,
    "total_amount": String,
    "status": Int,
    "msg": String,
    "client_ip": String,
    "payer": {
        "name": String,
        "phone": String,
        "email": String
    },
    "shippingAddress": {
        "country": String,
        "addressLine": ArrayString,
        "region": String,
        "city": String,
        "dependentLocality": String,
        "postalCode": String,
        "sortingCode": String,
        "languageCode": String,
        "organization": String,
        "recipient": String,
        "phone": String
    },
    "shippingOption": String,
    "billingAddress": {
        "country": String,
        "addressLine": ArrayString,
        "region": String,
        "city": String,
        "dependentLocality": String,
        "postalCode": String,
        "sortingCode": String,
        "languageCode": String,
        "organization": String,
        "recipient": String,
        "phone": String
    },
    "methodName": String ("apple_pay")
    "requestId": String,
    "card": {
        "lastfour": String,
        "funding": Int,
        "type": Int,
    },
    "card_info": {
        "bincode": String,
        "lastfour": String,
        "issuer": String,
        "issuer_zh_tw": String,
        "bank_id": String,
        "funding": Int,
        "type": Int,
        "level": String,
        "country": String,
        "countrycode", String,
    },
    "merchant_reference_info": {
        "affiliate_codes": ArrayString,
    },
    "prime_expiry_millis": Number
}


Name Type Content
prime String A one-time token that represents a customer’s card.
You would need this token to pay in the Pay by Prime API.
total_amount String This Transaction total amount.
status Int Response code. 0 indicates success.
msg String Error message
client_ip String Customer IP Address
payer JSONObject Customer Information
NameTypeContent
nameStringCustomer’s name
phoneStringCustomer’s phone number
emailStringCustomer’s email
shippingAddress JSONObject Delivery address information
NameType
countryString
addressLineArrayString
regionString
cityString
dependentLocalityString
postalCodeString
sortingCodeString
languageCodeString
organizationString
recipientString
phoneString
shippingOption String Delivery method
billingAddress JSONObject
NameType
countryString
addressLineArrayString
regionString
cityString
dependentLocalityString
postalCodeString
sortingCodeString
languageCodeString
organizationString
recipientString
phoneString
methodName String (“card” , “android_pay” , “google_pay” or “apple_pay”)
requestId String Unique payment request identifier.
card JSONObject
NameTypeContent
lastfourStringLast four digits of the card
fundingIntCard usage
0 = Credit Card
1 = Debit Card
2 = Prepaid Card
typeIntCard type
1 = VISA
2 = MasterCard
3 = JCB
4 = Union Pay
5 = AMEX
card_info JSONObject Card information:
NameType(Max)Usage
bincodeString(6)First six digits of the card
lastfourString(4)Last four digits of the card
issuerStringCard issuer
issuer_zh_twStringIssuer chinese name
bank_idStringBank identifier
fundingint Card usage
-1 = Unknown
0 = credit card
1 = debit card
2 = prepaid card
typeintCard type
-1 = Unknown
1 = VISA
2 = MasterCard
3 = JCB
4 = Union Pay
5 = AMEX
levelStringCard level
countryStringCountry of card issuer
countrycodeStringCountry code of card issuer
merchant_reference_info JSONObject If the merchant uses the co-branded card management in the TapPay portal, and the transaction card number meets the setting, this parameter will be returned.

Set in TapPay Portal, must limit 20 character and half alphanumeric.
Not support : JKOPAY
NameTypeContent
affiliate_codesArrayAffiliated codes set by the merchant in the Co-brand card management area of ​​the TapPay portal.
prime_expiry_millis Number Prime Expiry Date
Fiexd return parameter on latest Web SDK version (From v5.3)

Example

If you have any questions, please refer our Example or Apple’s Apple Pay Example(https://developer.apple.com/library/content/samplecode/EmporiumWeb/Introduction/Intro.html “Apple Example Project”).
Keep in mind that Apple Pay JavaScript API is only available on iOS device running iOS 10 or later or Mac running macOS Sierra (10.12) or later.

Reference

If you want to integrate more payment methods, please refer to Payment Request API

Q&A

If you have to set frame-src of Content Security Policy, please set following two domains.

  1. js.tappaysdk.com
  2. fraud.tappaysdk.com