EasySafePay (iOS)
This article introduces the integration solution to support accepting payments from a desktop browser or mobile browser. After integration, you can access various payment methods like digital wallets, bank cards, and bank transfers.
User experience
The following screenshots show the user experience of wallet and bank transfer. During the first-time payments, buyers can enable password-free payment for subsequent payments. The entire payment process for subsequent payments will be performed on your website or application.
Wallet
With the entire payment process remaining within your website or application, buyers are allowed to pay and enable password-free payments during their first-time payments and make subsequent payments without the need to enter the payment password.
First-time payment using wallet
During the first-time payments, the buyer completes the authorization process to pay and enable subsequent password-free payments.
Bank transfer
For bank transfer payment methods, the following graphics show the user experience for the first-time and subsequent payments.
First-time payment using bank transfer
During the first-time payments, users need to enter the payment password and verification number.
Payment flow
First-time payment
When a buyer selects a payment method provided by Antom, you need to collect essential information including the payment request ID, order amount, payment method, order description, payment redirect page URL, and payment result notification URL. Susequently, call the createPaymentSession (EasySafePay) API to place orders and call relevant methods in the Antom SDK to facilitate the payment process.
- The buyer lands on the checkout page.
- Create the createPaymentSession (EasySafePay) request.
After the buyer selects a payment method and submits the order, you can obtain the payment session by calling the createPaymentSession (EasySafePay) API. - Invoke the client SDK.
On the client side, invoke the SDK through the payment session. The SDK will collects payment elements, displays code information, redirects, invokes, and guides the buyer to complete the payment based on the payment method's characteristics. - Get the authorization result.
- Asynchronous Notification: When the authorization is successful, Antom sends you the asynchronous notification through the notifyAuthorization API.
- Synchronous Inquiry: Call the inquiryPayment API to check the authorization status.
- Get the payment result.
Obtain the payment result by using one of the following two methods:
- Asynchronous Notification: Specify the paymentNotifyUrl in the createPaymentSession (EasySafePay) API to set the address for receiving asynchronous notifications. When the payment is successful or expires, Antom will use notifyPayment to send asynchronous notifications to you.
- Synchronous Inquiry: Call the inquiryPayment API to check the payment status.
Integration step
Start your integration by taking the following steps:
- Create a payment session
- Invoke the SDK
- Obtain the authorization or payment result
Step 1: Create a payment session
When a buyer selects a payment method provided by Antom, you need to collect essential information including the payment request ID, order amount, payment method, order description, payment redirect page URL, and payment result notification URL. Susequently, call the createPaymentSession (EasySafePay) API to create a payment session by completing these steps:
- Install an API library
- Initialize the request instance
- Call the createPaymentSession (EasySafePay) API
Note: Antom provides server-side API libraries for multiple languages. The following codes use Java as an example. You need to install Java 6 or higher.
Install an API library
You can find the latest version on GitHub.
<dependency>
<groupId>com.alipay.global.sdk</groupId>
<artifactId>global-open-sdk-java</artifactId>
<version>2.0.21</version>
</dependency>
Initialize the request instance
Create a singleton resource to make a request to Antom.
import com.alipay.global.api.AlipayClient;
import com.alipay.global.api.DefaultAlipayClient;
String merchantPrivateKey = "YOUR PRIVATE KEY";
String alipayPublicKey = "ALIPAY PUBLIC KEY";
AlipayClient defaultAlipayClient = new DefaultAlipayClient(EndPointConstants.SG,
merchantPrivateKey, alipayPublicKey);
Create a payment session
Parameter name | Required | Description |
paymentMethod.paymentMethodId | ✅ | Pass in the value of accessToken in the notifyAuthorization API received after the first payment. |
paymentRedirectUrl | ✅ | The merchant page URL that the buyer is redirected to after the payment is completed. |
paymentNotifyUrl | ✅ | Payment result notification address. This address must be HTTPS. |
paymentSessionExpiryTime | Timeout for payment session. Default is 1 hour, can be set to a timeout within 1 hour, the format of the value follows the ISO 8601 standard. For example, 2019-11-27T12:01:01+08:00. | |
order.buyer: referenceBuyerId/buyerPhoneNo/buyerEmail | Pass in user information for risk decisions. Pass in referenceBuyerId, buyerPhoneNo, buyerEmail One of these parameters is sufficient. |
First-time payment
Call the createPaymentSession (EasySafePay) API to create a payment session by specifying the following parameters:
Parameter name | Required | Description |
paymentRedirectUrl | ✅ | The merchant page URL that the buyer is redirected to after the payment is completed. |
authState | ✅ | The unique identifier assigned by you to initiate the authorization, which is used to obtain tokens for subsequent secret-free payments. This parameter must be passed only for the first payment, you do not need to pass this parameter for subsequent payments. |
paymentNotifyUrl | ✅ | Payment result notification address. This address must be HTTPS. |
paymentSessionExpiryTime | Timeout for payment session. Default is 1 hour, can be set to a timeout within 1 hour, the format of the value follows the ISO 8601 standard. For example, 2019-11-27T12:01:01+08:00. | |
userLoginId | The buyer's wallet side login account, which can be the buyer's email address or phone number. | |
order.buyer: referenceBuyerId/buyerPhoneNo/buyerEmail | Pass in buyer information for risk decisions. Pass in referenceBuyerId, buyerPhoneNo, buyerEmail One of these parameters is sufficient. |
Parameters listed above are not comprehensive. See the createPaymentSession (EasySafePay) API for a complete list of parameters and any additional requirements for specific payment methods.
The following sample code shows how to call the createPaymentSession (EasySafePay) API:
AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
alipayPaymentSessionRequest.setClientId(clientId);
alipayPaymentSessionRequest.setPath("/ams/sandbox/api/v1/payments/createPaymentSession");
alipayPaymentSessionRequest.setProductCode(ProductCodeType.AGREEMENT_PAYMENT);
alipayPaymentSessionRequest.setProductScene(ProductSceneConstants.EASY_PAY);
// replace to your paymentRequestId
alipayPaymentSessionRequest.setPaymentRequestId("paymentRequestId001");
Amount amount = new Amount();
// set amount
amount.setCurrency("CNY");
amount.setValue("100");
alipayPaymentSessionRequest.setPaymentAmount(amount);
//set settlement currency
SettlementStrategy settlementStrategy = new SettlementStrategy();
settlementStrategy.setSettlementCurrency("USD");
alipayPaymentSessionRequest.setSettlementStrategy(settlementStrategy);
// set agreementInfo
AgreementInfo agreementInfo = new AgreementInfo();
agreementInfo.setAuthState("authState001");
agreementInfo.setUserLoginId("userLoginId001");
alipayPaymentSessionRequest.setAgreementInfo(agreementInfo);
// set paymentMethod
PaymentMethod paymentMethod = new PaymentMethod();
paymentMethod.setPaymentMethodType("ALIPAY_CN");
// set order Info
Order order = new Order();
order.setReferenceOrderId("referenceOrderId001");
order.setOrderDescription("orderDescription001");
order.setOrderAmount(amount);
Buyer buyer = new Buyer();
buyer.setReferenceBuyerId("referenceBuyerId001");
order.setBuyer(buyer);
order.setOrderAmount(amount);
alipayPaymentSessionRequest.setOrder(order);
// replace to your redirect url
alipayPaymentSessionRequest.setPaymentNotifyUrl("https://www.yourNotifyUrl");
alipayPaymentSessionRequest.setPaymentRedirectUrl("https://www.yourMerchantWeb.com");
AlipayPaymentSessionResponse alipayPaymentSessionResponse = defaultAlipayClient
.execute(alipayPaymentSessionRequest);
The following code shows a sample of the request message:
{
"settlementStrategy": {
"settlementCurrency": "USD"
},
"productCode": "AGREEMENT_PAYMENT",
"productScene": "EASY_PAY",
"paymentNotifyUrl": "https://www.yourNotifyUrl",
"paymentRequestId": "paymentRequestId001",
"paymentRedirectUrl": "https://www.yourMerchantWeb.com",
"paymentMethod": {
"paymentMethodType": "ALIPAY_CN"
},
"agreementInfo": {
"authState": "authState001",
"userLoginId":"userLoginId001"
},
"paymentAmount": {
"currency": "CNY",
"value": "100"
},
"order": {
"orderAmount": {
"currency": "CNY",
"value": "100"
},
"referenceOrderId": "referenceOrderId001",
"orderDescription": "orderDescription001",
"buyer":{
"referenceBuyerId":"referenceBuyerId001"
}
}
}
The following code shows a sample of the response, which contains the following parameters:
- paymentSessionData: the payment session data, which needs to be forwarded to your client.
- paymentSessionExpiryTime: the expiration time of the payment session.
{
"paymentSessionData": "UNvjVWnWPXJA4BgW+vfjsQj7PbOraafHY19X+6EqMz6Kvvmsdk+akdLvoShW5avHX8e8J15P8uNVEf/PcCMyXg==&&SG&&111",
"paymentSessionExpiryTime": "2023-04-06T03:28:49+08:00",
"paymentSessionId": "UNvjVWnWPXJA4BgW+vfjsQj7PbOraafHY19X+6EqMz6Ikyj9FPVUOpv+DjiIZqMe",
"result": {
"resultCode": "SUCCESS",
"resultMessage": "success.",
"resultStatus": "S"
}
}
Common questions
Q: Can I use Chinese characters in the value of the request parameters?
A: To avoid incompatibility of a certain payment method, do not use Chinese characters for fields in the request.
Q: How to set the URL to receive the payment notification?
A: Specify paymentNotifyUrl in the createPaymentSession API to receive the asynchronous notification about the payment result (notifyPayment), or configure the receiving URL in Antom Dashboard. If the URL is specified in both the request and Antom Dashboard, the value specified in the request takes precedence.
Step 2: Create and invoke the SDK
Install
Version requirements:
- Install Xcode 12 or a higher version.
- Use iOS 11 or a higher version.
To integrate the SDK package, refer to Integrate the SDK Package.
Instantiate the Client SDK
Create an SDK instance and specify basic configurations. Creating an AMSEasyPayConfiguration object includes the following parameters:
Parameter name | Required | Description |
locale | Used to specify the language information. Select the appropriate value based on the region of the payment method. Valid values for this parameter are listed as follows. If a value not in the following list is used, the local language is used instead.
| |
options | Used to specify whether to use the default loading pattern and the sandbox environment. Valid values are:
|
Implementing AMSPaymentProtocol
used for handling corresponding events in subsequent processes. It contains the following method:
Method | Required | Description |
onEventCallback | A callback function that monitors payment events on the checkout page, returning eventCode and eventResult. |
Implementing the AMSLoggerProtocol
used to manage log output. It contains the following method:
Method | Required | Description |
logWithName | A callback function used to output logs by default. |
The following sample code shows how to instantiate the SDK:
#import <AMSComponent/AMSComponent-Swift.h>
AMSEasyPayConfiguration *componentConfig = [AMSEasyPayConfiguration new];
componentConfig.locale = @"en_US";
// Specify showLoading as true (default value) to use the default loading pattern. Specify it as false to customize the loading animation based on onEventCallback.
// Set the sandbox environment. If you leave it empty, the production environment is used by default.
NSDictionary *options = @{@"showLoading": @"true", @"sandbox": @"true"};
componentConfig.options = options;
[[AMSEasyPay shared] initConfiguration:componentConfig];
// Set the callback to monitor payment events on the checkout page.
[AMSEasyPay shared].paymentDelegate = self;
[AMSEasyPay shared].loggerDelegate = self;
// The server calls the createPaymentSession API to obtain paymentSessionData.
Invoke the SDK
Call the createComponent
method:
Parameter name | Required | Description |
sessionData | ✅ | Create a configuration object by using the sessionData parameter: Use the complete data of the value of paymentSessionData obtained in the response of the createPaymentSession (EasySafePay) API as the value of this parameter. |
Call onDestroy
to free SDK component resources in the following situations:
- When the buyer exits the checkout page, free the component resources created in the createPaymentSession (EasySafePay) API.
- When the buyer initiates multiple payments, free the component resources created in the previous createPaymentSession (EasySafePay) API.
The following sample code shows how to invoke the SDK:
[[AMSEasyPay shared] createComponent:sessionData];
//Free SDK component resources
[[AMSEasyPay shared] onDestroy];
Step 3: Obtain authorization result or payment result
For first-time payments, you can obtain both the authorization and payment results, while for subsequent payments, only the payment result is available.
You can obtain the authorization or payment result by one of the following methods:
- Receive the asynchronous notification
- Inquire about the result
Receive the asynchronous notification
Obtain the authorization result
When the authorization is successful, Antom sends you the asynchronous notification through the notifyAuthorization API. When you receive the notification, you must return a response as instructed in Return a receipt acknowledgment message. Meanwhile, you must update the authorization status of the buyer in your system and display the buyer's desensitized account obtained from the notification on your authorization management page.
The following code shows a sample of the notification request:
{
"accessToken": "2810123456789012345678901234567890",
"authState": "AUTHSTATE_SAMPLE_1234567890",
"authorizationNotifyType": "TOKEN_CREATED",
"userLoginId": "852-52***184",
"result": {
"resultCode": "SUCCESS",
"resultMessage": "success.",
"resultStatus": "S"
}
}
How to verify the signature of the notification and make a response to the notification, see Sign a request and verify the signature.
Common questions
Q: When will the payment result notification be sent?
A: It depends on whether the payment is completed:
- If the payment is successfully completed, Antom will usually send you an asynchronous notification within 3 to 5 seconds. For some payment methods like OTC, the notification might take a bit longer.
- If the payment is not completed, Antom needs to close the order first before sending an asynchronous notification. The time it takes for different payment methods to close the order varies, usually defaulting to 14 minutes.
Q: Will the asynchronous notification be re-sent?
A: Yes, the asynchronous notification will be re-sent automatically within 24 hours for the following cases:
- If you didn't receive the asynchronous notification due to network reasons.
- If you receive an asynchronous notification from Antom, but you didn't make a response to the notification in the Sample code format.
The notification can be resent up to 8 times or until a correct response is received to terminate delivery. The sending intervals are as follows: 0 minutes, 2 minutes, 10 minutes, 10 minutes, 1 hour, 2 hours, 6 hours, and 15 hours.
Q: When responding to asynchronous notification, do I need to add a digital signature?
A: If you receive an asynchronous notification from Antom, you are required to return the response in the Sample code format, but you do not need to countersign the response.
Q: What are the key parameters in the payment result notification that I need to use?
A: Pay attention to the following key parameters:
- result: indicates the payment result of the order.
- paymentRequestId: indicates the payment request number you generated for consult, cancel, and reconciliation.
- paymentId: indicates the payment order number generated by Antom used for refund and reconciliation.
- paymentAmount: indicates the payment amount.
Q: What are the key parameters in the authorization result notification that I need to use?
A: Pay attention to the following key parameters:
- result: represents the payment result of the order.
- authState: the vaulting request ID generated by the merchant.
- accessToken: the auto debit ID generated by Antom used for subsequent payment.
- userLoginId: the user's desensitized account number.
Inquire about the payment result
You can call the inquiryPayment API to initiate a query on the result of an order.
Parameter name | Required | Description |
paymentRequestId | The payment request ID generated by you. |
The parameter is not a full set of parameters, please refer to the inquiryPayment API for full set of parameters and additional requirements for certain payment methods.
The following sample code shows how to call the inquiryPayment API:
AlipayClient defaultAlipayClient = new DefaultAlipayClient(EndPointConstants.SG,
merchantPrivateKey, alipayPublicKey);
AlipayPayQueryRequest alipayPayQueryRequest = new AlipayPayQueryRequest();
alipayPayQueryRequest.setClientId(CLIENT_ID);
alipayPayQueryRequest.setPath("/ams/sandbox/api/v1/payments/inquiryPayment");
AlipayPayQueryResponse alipayPayQueryResponse;
try {
alipayPayQueryResponse = defaultAlipayClient.execute(alipayPayQueryRequest);
} catch (AlipayApiException e) {
String errorMsg = e.getMessage();
// handle error condition
}
The following code shows a sample of the request message:
{
"paymentRequestId": "2019060811401080010018882020035****"
}
The following code shows a sample of the response message:
{
"result": {
"resultCode": "SUCCESS",
"resultStatus": "S",
"resultMessage": "Success"
},
"paymentStatus": "SUCCESS",
"paymentRequestId": "pay_1089760038715669_10277574507XXXX",
"paymentId": "2019060811401080010018882020035XXXX",
"paymentAmount": {
"value": "4200",
"currency": "SGD"
},
"paymentCreateTime": "2019-06-01T12:01:01+08:30",
"paymentTime": "2019-06-01T12:01:01+08:30",
"transactions": null
}
Common questions
Q: How often should I call the inquiryPayment API?
A: Call the inquiryPayment API constantly with an interval of 2 seconds until the final payment result is obtained or an asynchronous payment result notification is received.
Q: What are the key parameters in the notification that I need to use?
A: Pay attention to these key parameters:
- result: represents the result of this inquiryPayment API call, the result of the order needs to be judged according to paymentStatus:
SUCCESS
andFAIL
represent the final result.PROCESSING
represents the processing.
- paymentAmount: indicates the payment amount.
Sample codes
Complete sample code for using the client SDK:
#import <AMSComponent/AMSComponent-Swift.h>
// Step 1: Create the AMSEasyPayConfiguration type.
AMSEasyPayConfiguration *componentConfig = [AMSEasyPayConfiguration new];
componentConfig.locale = @"en_US";
// Specify showLoading as true (default value) to use the default loading pattern. Specify it as false to customize the loading animation based on onEventCallback.
// Set the sandbox environment. If you leave it empty, the production environment is used by default.
NSDictionary *options = @{@"showLoading": @"true", @"sandbox": @"true"};
componentConfig.options = options;
[[AMSEasyPay shared] initConfiguration:componentConfig];
// Set the callback to monitor payment events on the checkout page.
[AMSEasyPay shared].paymentDelegate = self;
[AMSEasyPay shared].loggerDelegate = self;
// Step 2: The server calls the createPaymentSession API to obtain paymentSessionData.
// Step 3: Create and render the Component.
[[AMSEasyPay shared] createComponent:paymentSessionData];
#pragma AMSPaymentProtocol
- (void)onEventCallback:(NSString *)eventCode eventResult:(AMSEventResult *)eventResult
{
NSLog(@"eventCode%@ eventResult%@", eventCode, eventResult);
}
#pragma AMSLogProtocol
- (void)logWithName:(NSString *)name parameter:(NSDictionary<NSString *,id> *)parameter
{
NSLog(@"name%@ parameter%@", name, parameter);
}
Event codes
You might see two types of event codes:
- Status codes: Returned by
onEventCallback
during the component's runtime lifecycle. - Error codes: Returned by
onEventCallback
oronError
during the component initialization phase.
Type | Code | Description | Further action |
Status codes | SDK_START_OF_LOADING | The loading animation starts to be shown when the component is created. When configured to hide loading and use a custom animation, the custom animation can be rendered at this time. | No further action. |
SDK_END_OF_LOADING | The loading animation ends when the component is created. When configured to hide loading and use custom animation, the animation can be hidden at this time. | No further action. | |
SDK_CALL_URL_ERROR |
In the Web or WAP scenario, redirecting links is usually not abnormal. It is recommended that you verify the redirected link. In the app scenario, if this exception frequently occurs, contact Antom Technical Support to troubleshoot redirection or calling issues. | No further action. | |
Error codes | SDK_INTERNAL_ERROR | SDK internal error. | Contact Antom Technical Support. |
SDK_CREATEPAYMENT_PARAMETER_ERROR | mountComponent method specified parameter abnormally. | Check if the parameters are correct and reinitialize the component. | |
SDK_INIT_PARAMETER_ERROR | AMSEasyPay method specified parameter abnormally. | Check if the parameters are correct and re-instantiate the SDK. | |
SDK_CREATECOMPONENT_ERROR | Component initialization exception. | Contact Antom Technical Support. | |
SDK_SUBMIT_NETWORK_ERROR | API call failed due to network reasons. It may occur in submit method submission. | Try to submit it again. |