Apple Pay
Preparations
Merchant Registration
For registration, you must provide your company name, domain name, and merchant ID (defined by Fireantpay). Apple Pay requires the Merchant ID provided by Fireantpay.
Sample request:
apple_pay_integrator_identity.pem --key platform_integrator_identity.key -H "Content-Type: application/json" -d '{
"domainNames": ["www.example.com"],
"encryptTo": "platformintegrator.com.fireantpay",
"partnerInternalMerchantIdentifier": "mer-example",
"partnerMerchantName": "EXAMPLE CO.LTD"
}'domainNames: Website domain namespartnerInternalMerchantIdentifier: Apple merchant IDpartnerMerchantName: Apple merchant name (usually your company name)
Merchant Website Verification
The merchant must upload the
apple-developer-merchantid-domain-associationfile provided by Fireantpay to your website.Verify that your website can access the file at:
https://xxx.com/.well-known/apple-developer-merchantid-domain-associationProvide your website domain (e.g.,
xxx.com) to Fireantpay to generate themerchantIdentifier.The front-end payment page must provide an Apple validation interface; validation information shall be forwarded to FireantPay via the merchant backend for merchant verification.
Validation endpoint: /api/applepay/validate
Front-end example (direct access to Fireantpay will cause CORS issues; submit to your merchant backend):
fetch('/api/applepay/validate', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
validationURL: event.validationURL,
merchantIdentifier: 'merchant.com.fireanttest',
domainName: window.location.hostname,
displayName: 'My Store'
})
})Back-end example:
// Prepare request payload to Fireantpay
JSONObject payload = new JSONObject();
String fireantpayValidateUrl = "https://secure.fireantpay.com/api/applepay/validate";
payload.put("merchantIdentifier", merchantIdentifier);
payload.put("domainName", domainName);
payload.put("displayName", displayName);
payload.put("validationURL", validationURL);
// 1. Create HTTPS connection
HttpsURLConnection connection = (HttpsURLConnection) new URL(fireantpayValidateUrl).openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
// 2. Send request
connection.setDoOutput(true);
try (OutputStream os = connection.getOutputStream()) {
os.write(payload.getBytes(StandardCharsets.UTF_8));
}
// 3. Parse response
if (connection.getResponseCode() != 200) {
throw new IOException("Apple Pay validation failed: " + connection.getResponseMessage());
}
try (InputStream is = connection.getInputStream()) {
String responseBody = new BufferedReader(new InputStreamReader(is))
.lines().collect(Collectors.joining("\n"));
return JSON.parseObject(responseBody);
}Payment Request
Payment Interface Request
- Fill in relevant information according to the example format.
- Submit fields using the exact field names in the table below; parameter names are case-sensitive.
- All commands sent to this system gateway use the POST method and UTF-8 encoding.
- Trim leading/trailing spaces from every parameter value before combining, encrypting, and submitting payment parameters.
Form Parameter Format Description
| Param Name | Type | Length | Required | Description |
|---|---|---|---|---|
| Order Information | ||||
| merNo | String | 5 | Yes | Merchant Number; unique ID assigned by the payment platform |
| gatewayNo | String | 8 | Yes | Gateway Access No.; unique ID for merchant access |
| orderNo | String | 50 | Yes | Store Order No.; unique, no duplicates in the same store system |
| orderCurrency | String | 3 | Yes | Payment currency (3-digit ISO 4217 code; see Appendix) |
| orderAmount | String | 10 | Yes | Total order amount; 2 decimal places, rounded if needed |
| shipFee | String | 100 | No | Shipping fee; numeric, max 2 decimals |
| discount | String | 100 | No | Discount; default negative, numeric, max 2 decimals |
| goodsInfo | String | 5000 | Yes | Detailed goods info; see Appendix: Goods Information |
| Credit Card Information | ||||
| cardNo | String | 200 | Yes | Credit card number; for Apple Pay: masked number (e.g., 4***********1111) |
| tradeType | String | 50 | Yes | Transaction type; fixed: APPLEPAY (required for wallet payments) |
| cardToken | String | 500 | Yes | Wallet payment token (required for APPLEPAY) |
| User Information | ||||
| firstName | String | 100 | Yes | First name |
| lastName | String | 50 | Yes | Last name |
| String | 200 | Yes | User email | |
| ip | String | 100 | Yes | User IP address |
| phone | String | 50 | Yes | User phone |
| country | String | 100 | Yes | User country (ISO 3166-1 2-letter code, e.g., US) |
| state | String | 100 | No | User state/province |
| city | String | 100 | Yes | User city |
| address | String | 500 | Yes | User detailed address |
| zip | String | 100 | Yes | User ZIP/postal code |
| Consignee Information | ||||
| shipFirstName | String | 100 | No | Consignee first name |
| shipLastName | String | 100 | No | Consignee last name |
| shipEmail | String | 100 | No | Consignee email |
| shipPhone | String | 100 | No | Consignee phone |
| shipCountry | String | 100 | No | Consignee country (ISO 3166-1 2-letter code) |
| shipState | String | 100 | No | Consignee state/province |
| shipCity | String | 100 | No | Consignee city |
| shipAddress | String | 100 | No | Consignee detailed address |
| shipZip | String | 100 | No | Consignee ZIP/postal code |
| Device/OS Information | ||||
| os | String | 50 | Yes | Cardholder OS |
| brower | String | 50 | Yes | Browser type |
| browerLang | String | 50 | Yes | Browser language |
| timeZone | String | 50 | Yes | Time zone |
| resolution | String | 50 | Yes | Screen resolution |
| newCookie | String | 500 | Yes | New cookie (current order cookie $$ old cookie) |
| oldCookie | String | 500 | No | Old cookie value |
| Other Information | ||||
| webSite | String | 200 | Yes | Source website domain |
| notifyUrl | String | 200 | Yes | Asynchronous notification URL; platform POSTs result here; reply OK |
| returnUrl | String | 200 | Yes | Real-time return URL; for 3D Secure redirection |
| signInfo | String | 32 | Yes | SHA256 signature; fixed order: merNo+gatewayNo+orderNo+orderCurrency+orderAmount+cardNo+tradeType+cardToken+merKey; no spaces or + . For details, please refer to the appendix: SHA256 Signature Method. |
| remark | String | 500 | No | Merchant custom remark (returned as-is) |
Payment Interface Response
Interface Description
After receiving and processing the merchant’s order, the gateway returns the payment result in real time in XML format with UTF-8 encoding.
Return Data Description
Parse the XML response first, then judge the payment result. See the example below.
Form Parameter Format Description
| Param Name | Type | Max Length | Description |
|---|---|---|---|
| merNo | String | 5 | Merchant Number |
| gatewayNo | String | 8 | Gateway Access No. |
| tradeNo | String | 50 | Platform transaction serial number (unique) |
| orderNo | String | 50 | Merchant order number |
| orderCurrency | String | 3 | Order currency (ISO 4217) |
| orderAmount | String | 10 | Order amount |
| orderStatus | String | 1 | Transaction status:-1=Pending 0=Failed 1=Success 5=Failed (3D abandoned) |
| orderInfo | String | 100 | Transaction result message |
| billAddress | String | 100 | Billing descriptor (success only) |
| returnType | String | 1 | Return type: 1(Browser real-time) 2(Server real-time) 3(Server asynchronous) |
| orderErrorCode | String | 50 | Error code; 00 = success |
| signInfo | String | 32 | SHA256 signature: merNo+gatewayNo+tradeNo+orderNo+orderCurrency+orderAmount+orderStatus+orderInfo+merKey |
| remark | String | 500 | Merchant remark (as-is) |
| redirectUrl | String | 500 | 3D Secure redirect URL |
Payment Return Example
<?xml version="1.0" encoding="UTF-8"?>
<respon>
<merNo>80000</merNo>
<gatewayNo>80000001</gatewayNo>
<tradeNo>N025050101235959566838</tradeNo>
<orderNo>Test-123456</orderNo>
<orderAmount>10.00</orderAmount>
<orderCurrency>USD</orderCurrency>
<orderStatus>1</orderStatus>
<orderErrorCode>00</orderErrorCode>
<orderInfo>Approved</orderInfo>
<paymentMethod>Credit Card</paymentMethod>
<returnType>2</returnType>
<billAddress>Test Descriptor</billAddress>
<signInfo>B359F45698D1CE8A341C64815D346C9EDA8F14657D997901EA4D30FFODFC232A</signInfo>
<remark></remark>
<redirectUrl></redirectUrl>
</respon>Common Errors
I0013: Signature Value (signInfo) Error
- Check
merKeycorrectness and case consistency. - Use SHA256 signature.
- Remove all leading/trailing spaces from combined parameters.
I0014: Test Gateway Access No. → Production Payment Gateway
- Use the test gateway during development.
- Contact support to switch the merchant number to production after testing.
I0015: Production Gateway Access No. → Test Payment Gateway
- After switching to production, update the submission URL in your code to the production endpoint.
E0008: Duplicate Payment
- Multiple submissions for the same order within a short window (≈30s) are blocked to prevent duplicate payments.
Appendix
Goods Information
Format (fixed order):
GoodsName#,#GoodsID#,#UnitPrice#,#Qty#;#NextGoods...- Separate fields with
#,# - Separate goods with
#;# - Use
0for empty values - Currency matches the order currency
- All symbols are half-width
Example:
Good1#,#ID1#,#10.00#,#2#;#Good2#,#ID2#,#15.50#,#1Transaction Currency ISO 4217
| Code | Description EN | Description CN |
|---|---|---|
| CNY | Chinese Yuan | 人民币 |
| USD | US Dollar | 美元 |
| HKD | Hong Kong Dollar | 港币 |
| GBP | Pound Sterling | 英镑 |
| JPY | Japanese Yen | 日元 |
| EUR | Euro | 欧元 |
| AUD | Australian Dollar | 澳元 |
| SGD | Singapore Dollar | 新加坡元 |
| NZD | New Zealand Dollar | 新西兰元 |
| TWD | New Taiwan Dollar | 台币 |
| KRW | South Korean Won | 韩元 |
| DKK | Danish Krone | 丹麦克朗 |
| MYR | Malaysian Ringgit | 马币 |
| THB | Thai Baht | 泰铢 |
| INR | Indian Rupee | 印度卢比 |
| PHP | Philippine Peso | 菲律宾比索 |
| CHF | Swiss Franc | 瑞士法郎 |
| SEK | Swedish Krona | 瑞典克朗 |
| ILS | Israeli New Shekel | 新谢克尔 |
| ZAR | South African Rand | 兰特 |
| RUB | Russian Ruble | 卢布 |
| NOK | Norwegian Krone | 挪威克朗 |
| AED | UAE Dirham | 迪拉姆 |
| ARS | Argentine Peso | 阿根廷比索 |
| BRL | Brazilian Real | 巴西雷亚尔 |
| MMK | Myanmar Kyat | 缅币 |
| CAD | Canadian Dollar | 加元 |
| COP | Colombian Peso | 哥伦比亚比索 |
| HUF | Hungarian Forint | 匈牙利福林 |
| IDR | Indonesian Rupiah | 印尼卢比 |
| KWD | Kuwaiti Dinar | 科威特第纳尔 |
| LAK | Laotian Kip | 老挝基普 |
| MXN | Mexican Peso | 墨西哥比索 |
| NGN | Nigerian Naira | 尼日利亚奈拉 |
| PLN | Polish Złoty | 波兰兹罗提 |
| QAR | Qatari Riyal | 卡塔尔里亚尔 |
| SAR | Saudi Riyal | 沙特里亚尔 |
| TRY | Turkish Lira | 新土耳其里拉 |
| VND | Vietnamese Dong | 越南盾 |
Error List
| Code | Description |
|---|---|
| I0001 | Merchant No. cannot be empty |
| I0002 | Gateway No. cannot be empty |
| I0003 | Encryption Value cannot be empty |
| I0004 | Merchant No. and Gateway No. mismatch |
| I0005 | Merchant No. not activated |
| I0006 | Merchant No. disabled |
| I0007 | Merchant No. does not exist |
| I0008 | Abnormal merchant status |
| I0009 | Gateway Access No. not activated |
| I0010 | Gateway Access No. disabled |
| I0011 | Gateway Access No. deleted |
| I0012 | Abnormal gateway status |
| I0013 | Invalid signInfo |
| I0014 | Test gateway → production interface |
| I0015 | Production gateway → test interface |
| I0016 | Gateway not bound to this interface |
| I0017 | Order No. cannot be empty |
| I0018 | Order No. over 50 chars |
| I0019 | Order amount cannot be empty |
| I0020 | Invalid order amount |
| I0021 | Amount must have ≤2 decimals and ≥0 |
| I0022 | Currency cannot be empty |
| I0023 | Invalid currency |
| I0024 | Return URL cannot be empty |
| I0025 | Return URL over 1000 chars |
| I0059 | Required parameter missing |
| I0060 | Invalid parameter length |
| I0061 | Successful txn exists for this order (24h) |
| I0062 | System exception |
| I0067 | Remark over 500 chars |
| I0068 | Two-party verification failed |
| I0069 | Please select payment method |
| I0070 | Please select payment type |
| I0071 | IP cannot be empty |
| I0072 | Invalid IP format |
| I0092 | Invalid payment method |
| I0115 | Order not found |
| I0132 | Transaction type cannot be empty |
| I0133 | Invalid transaction type |
| I0134 | Appid cannot be empty |
| I0135 | Openid cannot be empty |
| I0136 | Goods info cannot be empty |
| R0000 | High risk |
| R0001 | Website not submitted/approved |
| R0002 | Cross-border transaction |
| C0001 | Gateway not bound to channel |
| C0002 | Rate not set |
| E0001 | Operation timeout |
| E0008 | Duplicate payment |
| T0001 | Test payment success |
| U0001 | Cardholder cancelled |
SHA256 Signature Method
Java
signInfo=sha256(merNo+gateWayNo+orderNo+orderCurrency+orderAmount+cardNo+tradeType+cardToken+merKey);PHP
$signInfo=hash("sha256",$merNo.$gateWayNo.$orderNo.$orderCurrency.$orderAmount.$cardNo.$tradeType.$cardToken.$merKey);ApplePay Format
- cardNo: The format of
cardNois a masked card number, where the first digit indicates the card brand (Visa: 4, Mastercard: 5, JCB: 35, AE: 34), and the last four digits are the actual last four digits of the card number. The middle part is padded with asterisks (*) to make a total length of 16 digits.(e.g.,4***********1111) - cardToken: full wallet token JSON
ApplePay Token Example
{
"paymentData": {
"data": "kTWMTlpcZV4VamhQGYL6O89tSn2zcyrvEJVUvdcBhro...",
"signature": "MIAGCSqGSIb3DQEHAqCAMIACAQExDTALBglghkgB...",
"header": {
"publicKeyHash": "nHSr4aTmUBLmIiCH15Y+ZbRt03L/c3FTaaR59iSGztc=",
"ephemeralPublicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1V+nhAGl86sIA49ZIPUCsBjw0v6MzVEUlrY1slTlC9DT5Q7cye7GJSI0yWMGfpvtrM1i4IqZVqOci7LAkBGAZg==",
"transactionId": "6b76240ac14c8231e009a43e28fb2206be0ce3f939cf2bbb605fc5ebd7f0ed4c"
},
"version": "EC_v1"
},
"paymentMethod": {
"displayName": "Visa 0121",
"network": "Visa",
"type": "credit"
},
"transactionIdentifier": "6b76240ac14c8231e009a43e28fb2206be0ce3f939cf2bbb605fc5ebd7f0ed4c"
}Payment Submission Example PHP
$data = array(
'merNo' => $merNo,
'gatewayNo' => $gatewayNo,
'orderNo' => $orderNo,
'orderAmount' => $orderAmount,
'orderCurrency' => $orderCurrency,
'shipFee' => $shipFee,
'firstName' => $firstName,
'lastName' => $lastName,
'email' => $email,
'phone' => $phone,
'zip' => $zip,
'address' => $address,
'city' => $city,
'state' => $state,
'country' => $country,
'shipFirstName' => $shipFirstName,
'shipLastName' => $shipLastName,
'shipPhone' => $shipPhone,
'shipEmail' => $shipEmail,
'shipCountry' => $shipCountry,
'shipState' => $shipState,
'shipCity' => $shipCity,
'shipAddress' => $shipAddress,
'shipZip' => $shipZip,
'returnUrl' => $returnUrl,
'notifyUrl' => $notifyUrl,
'shipMethod' => $shipMethod,
'signInfo' => $signInfo,
'cardNo' => $cardNo,
'cardToken' => $cardToken,
'tradeType' => $tradeType,
'ip' => $ip,
'os' => $os,
'brower' => $brower,
'browerLang' => $browerLang,
'timeZone' => $timeZone,
'resolution' => $resolution,
'goodsInfo' => $goodsInfo,
'oldCookie' => $oldCookie,
'newCookie' => $newCookie
);
// Submit via CURL to FireAnt Payment Gateway
$result = curl_post('https://sandbox.fireantpay.com/TPInterface', http_build_query($data));
$xmlstring = simplexml_load_string($result, 'SimpleXMLElement', LIBXML_NOCDATA);
$value_array = json_decode(json_encode($xmlstring), true);
// Redirect to 3D Secure if redirectUrl exists
if (!empty($value_array['redirectUrl'])) {
header('Location:'.$value_array['redirectUrl']);
exit;
}
// Get order status
$orderStatus = $value_array['orderStatus'];
if ($orderStatus == "1") {
echo "Payment Successful";
}