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
- 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:
|
|||||||||||||||||||||||||||||||||
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
|
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.
- The items of
TPDCart
are amount pending items and total amount is set to show 『AMOUNT PENDING』(self.cart.isAmountPending = true
). - 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 |
|
||||||||||||||||||
total | JSONObject |
|
||||||||||||||||||
shippingOptions | JSONObject |
|
||||||||||||||||||
options | JSONObject |
|
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 |
|
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.
isAmountPending:true
has been set in all displayItems of paymentRequest and total amount is set to show 『AMOUNT PENDING』(total.isShowTotalAmount:false
)- The total of displayItems’ amount is 0 and total amount is set to show 『AMOUNT PENDING』(
total.isShowTotalAmount:false
) - 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
|
|||||||||||||||||||||||||||||||||
shippingAddress | JSONObject | Delivery address information
|
|||||||||||||||||||||||||||||||||
shippingOption | String | Delivery method | |||||||||||||||||||||||||||||||||
billingAddress | JSONObject |
|
|||||||||||||||||||||||||||||||||
methodName | String | (“card” , “android_pay” , “google_pay” or “apple_pay”) | |||||||||||||||||||||||||||||||||
requestId | String | Unique payment request identifier. | |||||||||||||||||||||||||||||||||
card | JSONObject |
|
|||||||||||||||||||||||||||||||||
card_info | JSONObject | Card information:
|
|||||||||||||||||||||||||||||||||
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
|
|||||||||||||||||||||||||||||||||
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.
- js.tappaysdk.com
- fraud.tappaysdk.com