Apple Pay Payment Authorization
Payment authorization is the final phase of Apple Pay integration, triggered after user biometric authentication and payment confirmation. This phase processes encrypted payment tokens through Onerway's infrastructure to complete transactions.
This document covers onpaymentauthorized
event handling and backend Onerway API integration.
Related sections: Merchant Validation
, Payment Initiation
, Session Initialization
, Troubleshooting
Process Overview
Payment authorization includes four steps:
- User authentication: Biometric authentication via Touch ID, Face ID
- Payment data collection: Encrypted tokens and contact information
- Payment processing: Submit encrypted data to Onerway for processing
- Session completion: End payment session with success or failure status
Authorization Flow
Payment Authorization Flow
Implementation Guide
Frontend Implementation
Handle the onpaymentauthorized
event on the frontend:
// Set up Apple Pay payment authorization event listener
session.onpaymentauthorized = function(event) {
// Get payment token and contact information
const paymentData = {
paymentToken: event.payment.token,
billingContact: event.payment.billingContact,
shippingContact: event.payment.shippingContact
// Add additional parameters as needed (orderId, amount, etc.)
};
// Submit to backend for processing
fetch('/api/apple-pay/process-payment', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(paymentData)
})
.then(response => response.json())
.then(result => {
if (result.success) {
// Payment successful, must call completePayment to end session
session.completePayment(ApplePaySession.STATUS_SUCCESS);
// TODO: Handle success workflow
} else {
// Payment failed, must call completePayment to end session
session.completePayment(ApplePaySession.STATUS_FAILURE);
// Handle failure workflow
showErrorMessage(result.error);
}
})
.catch(error => {
// Handle exceptions, must call completePayment to end session
session.completePayment(ApplePaySession.STATUS_FAILURE);
console.error('Payment processing error:', error);
});
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Note: Only call STATUS_SUCCESS
when the backend confirms transaction success (e.g., respCode = 20000
and data.status = "S"
); otherwise call STATUS_FAILURE
.
Important Notice
Whether payment succeeds or fails, you must call the session.completePayment()
method to end the Apple Pay session, otherwise the session will remain in a waiting state.
Backend Implementation
Note
- All
JSON
fields must be stringified before submission - Nested objects must be serialized to
JSON
string format JSON
fields must not contain unescaped special characters- Arrays in
JSON
should be properly formatted - Example of
JSON
string field:
{
"object": "{\"obj-key1\":\"v1\",\"obj-key2\":\"v2\"}",
"complex": "{\"k1\":\"v1\",\"array\":\"[{\\\"obj-key3\\\":\\\"v3\\\",\\\"obj-key4\\\":\\\"v4\\\"}]\"}"
}
2
3
4
Apple Pay Request Parameters
Parameter | Type | Length | Required | Signed | Description |
---|---|---|---|---|---|
billingInformation | String | / | Yes | Yes | Transaction billing information in JSON string format. See TransactionAddressfor complete structure. |
merchantCustId | String | 50 | Conditional | Yes | Unique customer identifier in merchant system. |
merchantNo | String | 20 | Yes | Yes | Merchant number assigned by |
merchantTxnId | String | 64 | Yes | Yes | Unique transaction identifier for each customer payment, generated by the merchant system. |
merchantTxnOriginalId | String | 128 | No | Yes | Master transaction ID generated by merchant for grouping related transactions. |
merchantTxnTime | String | / | No | Yes | Transaction timestamp when the merchant initiated the transaction. |
merchantTxnTimeZone | String | 64 | No | Yes | Transaction timezone offset for the merchant transaction time. |
orderAmount | String | 19 | Yes | Yes | Transaction amount in the specified currency, formatted as a decimal string. |
orderCurrency | String | 8 | Yes | Yes | |
productType | String | 16 | Yes | Yes | Payment method category that determines which payment options are available to customers. See ProductTypeEnumfor all available options. |
shippingInformation | String | / | Yes | Yes | Transaction shipping information in JSON string format. See TransactionAddressfor complete structure. |
sign | String | / | Yes | No | Digital signature string for request verification and security. Please refer to Signature for signature generation method. |
subProductType | String | 16 | Yes | Yes | Specific implementation method within the selected product type, defining how the payment is processed. See SubProductTypeEnumfor all available options. |
tokenInfo | String | / | Conditional | Yes | Token information in JSON string format. See TokenInfofor complete structure. |
txnOrderMsg | String | / | Yes | Yes | Transaction business information in JSON string format. See TxnOrderMsgfor complete structure. |
txnType | String | 16 | Yes | Yes | Transaction type that defines the payment operation to be performed. See TxnTypeEnumfor all available options and detailed usage scenarios. |
TokenInfo Parameter Description
Important: Apple Pay payment tokens must be assigned to the tokenInfo.tokenId
field
Name | Type | Length | Required | Description |
---|---|---|---|---|
tokenId | String | / | Yes | Token ID from payment method binding. For digital wallets: • Apple Pay: Use • Google Pay: Use |
provider | String | / | Conditional | Token provider. Defaults to for other scenarios. |
Response
Name | Type | Description |
---|---|---|
respCode | String | Response code from |
respMsg | String | Response message from |
data | Object | Response data. Refer to object data |
data
Name | Type | Description |
---|---|---|
transactionId | String | Transaction order number created by |
responseTime | String | Interface response time Format: |
txnTime | String | Transaction completion time Format: |
txnTimeZone | String | Transaction time zone Format: |
orderAmount | String | Order amount |
orderCurrency | String | |
txnAmount | String | Order amount after conversion to settlement currency |
txnCurrency | String | |
status | String | Transaction processing result Refer to TxnStatusEnum |
redirectUrl | String | Redirection URL for 3D Secure verification |
contractId | String | Subscription contract number |
tokenId | String | Payment token |
eci | String | Electronic Commerce Indicator |
periodValue | String | Installment payment number of periods |
codeForm | String | Code form for specific payment methods See CodeFormEnum |
presentContext | String | Context information for presentation layer |
actionType | String | Action type for the transaction See ActionTypeEnum |
subscriptionManageUrl | String | Subscription management URL |
sign | String |
API Usage Examples
{
"tokenInfo": "{\"provider\":\"ApplePay\",\"tokenId\":\"{...ApplePay token JSON...}\"}"
}
2
3
{
"billingInformation": "{\"address\":\"889 Mill Close\",\"city\":\"Buckridgefield\",\"country\":\"US\",\"email\":\"Ryan.Purdy@gmail.com\",\"firstName\":\"Frederik\",\"identityNumber\":\"92066033023\",\"lastName\":\"Pfannerstill\",\"phone\":\"15209608948\",\"postalCode\":\"96542\",\"province\":\"CO\"}",
"cardInfo": "{\"cvv\":\"123\"}",
"merchantCustId": "CustId-75S6-256P",
"merchantNo": "800209",
"merchantTxnId": "0104b16f-cc96-44ed-94bd-e814f6b64bec",
"merchantTxnTime": "2025-06-25 20:18:57",
"orderAmount": "1",
"orderCurrency": "USD",
"productType": "CARD",
"shippingInformation": "{\"address\":\"72981 Alejandrin Port\",\"city\":\"Lake Judd\",\"country\":\"US\",\"email\":\"Tracy_Stanton58@gmail.com\",\"firstName\":\"Noble\",\"identityNumber\":\"84880795738\",\"lastName\":\"Baumbach\",\"phone\":\"18434119887\",\"postalCode\":\"12053\",\"province\":\"CO\"}",
"sign": "8816e1f0326f2ee34f8bc909f7cd5d259aed37e59410f178d22f275f2f38fbe9",
"subProductType": "DIRECT",
"tokenInfo": "{\"provider\":\"ApplePay\",\"tokenId\":\"{\\\"paymentData\\\":{\\\"data\\\":\\\"Zg8fgQuOqRemQ7XPmartChBCZbfaaWBEk6AVRS6bcO7Qfqmm90S90l1nnsYKqwBMmDQcpsOfFF+HHgMAGwzo1XurrbZprbZc1Quw6mNJMrLwMiUMva4hf2sNNGCp9EHeSMx+MofeeMbHjI5fladdD19/GzXVNR1OAFdfuZLB/rkTKI5cVsKFqzeshxJiUAbHQvAwkdNvyjpEuGoWhSrWpaAbX6SBB6NlcUXQ4KT46LJJ+05QiwIO+drTdP9j/0Fbl+lg2UYcQPIE/3lownbSRPOq9JMpqF4xOZmO+3gYOaME5Xhev95g8kG3Hogw6MYBpGxmRA5Btu9Cma9fNEekA+KXqS78TQT24IktEpYUW9yKO+xUXTWqg0auFwb1bKOo2D2rSIAoYSW6Vnehdo0gmLP4BApyDf5Nug1YQEaKoKk=\\\",\\\"signature\\\":\\\"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\\\",\\\"header\\\":{\\\"publicKeyHash\\\":\\\"H8goTIjHUSUL1pcwkMV8ljgmU73N51JAIvz6Ti05LlI=\\\",\\\"ephemeralPublicKey\\\":\\\"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEV5gfSdV5Hf71RaGUoqrwQitC7SE7A/uQ7biDcM41u7ksBeIEeoBDGs4koPA8vDLDn9kgpEC38aXpBqvHp4IREw==\\\",\\\"transactionId\\\":\\\"fc46411c0070e4ca0ed2de2a7a12b9796ba94f00b72c4bdf406a1deb03d7487b\\\"},\\\"version\\\":\\\"EC_v1\\\"},\\\"paymentMethod\\\":{\\\"displayName\\\":\\\"Visa 0121\\\",\\\"network\\\":\\\"Visa\\\",\\\"type\\\":\\\"credit\\\"},\\\"transactionIdentifier\\\":\\\"fc46411c0070e4ca0ed2de2a7a12b9796ba94f00b72c4bdf406a1deb03d7487b\\\"}\"}",
"txnOrderMsg": "{\"accept\":\"*/*\",\"appId\":\"1727880846378401792\",\"colorDepth\":\"24\",\"contentLength\":\"65536\",\"javaEnabled\":false,\"language\":\"en-US\",\"products\":\"[{\\\"currency\\\":\\\"USD\\\",\\\"name\\\":\\\"butternut pumpkin\\\",\\\"num\\\":\\\"96\\\",\\\"price\\\":\\\"708.69\\\",\\\"type\\\":\\\"est\\\"},{\\\"currency\\\":\\\"USD\\\",\\\"name\\\":\\\"kiwi fruit\\\",\\\"num\\\":\\\"35\\\",\\\"price\\\":\\\"276.59\\\",\\\"type\\\":\\\"amet aliquip eiusmod\\\"}]\",\"returnUrl\":\"https://docs.onerway.com/\",\"notifyUrl\":\"https://sandbox-acq.onerway.com/callback/testReceiveNotification\",\"screenHeight\":\"1200\",\"screenWidth\":\"375\",\"timeZoneOffset\":\"180\",\"transactionIp\":\"252.238.110.248\",\"userAgent\":\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36\"}",
"txnType": "SALE"
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Note: tokenInfo
must be sent as an object (not a string). Example with object-form tokenInfo
:
{
"merchantNo": "800209",
"merchantTxnId": "0104b16f-cc96-44ed-94bd-e814f6b64bec",
"orderAmount": "1",
"orderCurrency": "USD",
"productType": "CARD",
"subProductType": "DIRECT",
"tokenInfo": {
"provider": "ApplePay",
"tokenId": {
"paymentData": { "data": "..." },
"paymentMethod": { "network": "Visa", "type": "credit" },
"transactionIdentifier": "..."
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"respCode": "20000",
"respMsg": "Success",
"data": {
"transactionId": "1962880981921042432",
"responseTime": "2025-09-02 22:11:13",
"txnTime": "2025-09-02 22:11:09",
"txnTimeZone": "+08:00",
"orderAmount": "1.00",
"orderCurrency": "USD",
"txnAmount": null,
"txnCurrency": null,
"status": "S",
"redirectUrl": null,
"contractId": null,
"tokenId": null,
"eci": null,
"periodValue": null,
"codeForm": null,
"presentContext": null,
"actionType": null,
"subscriptionManageUrl": null,
"sign": "719c7533ebe9b57dfc232176091eda1242a228045ffa6481d6a3bb048ff6a20e"
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
"notifyType": "TXN",
"transactionId": "1962880981921042432",
"txnType": "SALE",
"merchantNo": "800209",
"merchantTxnId": "0104b16f-cc96-44ed-94bd-e814f6b64bec",
"responseTime": "2025-09-02 22:11:13",
"txnTime": "2025-09-02 22:11:09",
"txnTimeZone": "+08:00",
"orderAmount": "1.00",
"orderCurrency": "USD",
"status": "S",
"cardBinCountry": "CA",
"reason": "{\"respCode\":\"20000\",\"respMsg\":\"Success\"}",
"sign": "b0cf37c8c79138a3248dc422de191416beb05d345110869045b3076819f7b2d8",
"paymentMethod": "VISA",
"walletTypeName": "ApplePay",
"channelRequestId": "8002091962880984022126593"
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Code Implementation Examples
@PostMapping("/api/apple-pay/process-payment")
public ResponseEntity<PaymentResponse> processPayment(@RequestBody ApplePayRequest request) {
// Build tokenInfo - key fields
Map<String, Object> tokenInfo = new HashMap<>();
tokenInfo.put("provider", "ApplePay"); // Must set to ApplePay
tokenInfo.put("tokenId", request.getPaymentToken()); // Payment token
// Build request parameters
Map<String, Object> params = new HashMap<>();
params.put("tokenInfo", tokenInfo); // Key: use tokenInfo
// TODO: Add other parameters
// Call Onerway API
OnerwayResponse result = callOnerwayAPI(params);
if ("20000".equals(result.getRespCode()) && "S".equals(result.getData().getStatus())) {
return ResponseEntity.ok(PaymentResponse.success(result.getData().getTransactionId()));
} else {
return ResponseEntity.ok(PaymentResponse.failure(result.getRespMsg()));
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
app.post('/api/apple-pay/process-payment', async (req, res) => {
const { paymentToken } = req.body;
const requestData = {
// Apple Pay uses tokenInfo field
tokenInfo: {
provider: 'ApplePay', // Must set to ApplePay
tokenId: paymentToken // Payment token
}
// TODO: Add other parameters
};
try {
const response = await fetch(`${BASE_URL}/v1/txn/doTransaction`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(requestData)
});
const result = await response.json();
if (result.respCode === '20000' && result.data.status === 'S') {
res.json({ success: true, transactionId: result.data.transactionId });
} else {
res.json({ success: false, error: result.respMsg || 'Payment failed' });
}
} catch (error) {
res.status(500).json({ success: false, error: 'Payment processing failed' });
}
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Key Points
tokenInfo.provider
must be set to"ApplePay"
tokenInfo.tokenId
must be the complete Apple Pay payment token object (fromevent.payment.token
)
Webhook Notifications
Handle Onerway payment result notifications:
@PostMapping("/webhooks/apple-pay")
public ResponseEntity<String> handleWebhook(@RequestBody OnerwayNotification notification, HttpServletRequest request) {
// Verify signature (per Onerway gateway spec)
if (!verifyOnerwaySignature(request, notification)) { // Verify notification authenticity
return ResponseEntity.status(401).body("Invalid signature");
}
// Update order status
updateOrderStatus(notification.getMerchantTxnId(), notification.getStatus()); // Update business status
// Confirm receipt with transaction ID (acknowledgement)
return ResponseEntity.ok(notification.getTransactionId()); // Must return transaction ID
}
2
3
4
5
6
7
8
9
10
11
12
13
app.post('/api/webhooks/apple-pay', async (req, res) => {
// Verify signature (per Onerway gateway spec)
if (!verifyOnerwaySignature(req)) { // Verify notification authenticity
return res.status(401).send('Invalid signature');
}
// Update order status
await updateOrderStatus(req.body.merchantTxnId, req.body.status); // Update business status
// Confirm receipt with transaction ID (acknowledgement)
res.send(req.body.transactionId); // Must return transaction ID
});
2
3
4
5
6
7
8
9
10
11
12
Note: Returning transactionId
is required by the Onerway gateway spec to acknowledge receipt of the notification.
Error Handling
Must call completePayment
to end the session based on payment results:
// Payment success
session.completePayment(ApplePaySession.STATUS_SUCCESS);
// Payment failed or exception
session.completePayment(ApplePaySession.STATUS_FAILURE);
2
3
4
5
Must Call completePayment
Regardless of payment results, you must call session.completePayment()
to end the Apple Pay session, otherwise the session will remain in a waiting state.
Security Essentials
Token Management:
- Never log or store Apple Pay payment tokens
- All payment communications must use HTTPS
- Always verify webhook signatures
Data Transmission:
- Ensure all API calls use HTTPS
- Verify payment token integrity
- Protect sensitive user information
Data Consistency & Replay Prevention:
- Validate orderId, amount, and currency against merchant-side order records
- Enforce idempotency (e.g., dedupe by
merchantTxnId
) and limit token usability window to prevent replays
For detailed practices, see Troubleshooting.
Best Practices
Performance Standards
- Configure appropriate timeouts (10-15 seconds)
- Monitor success rates and response times
- Optimize network request processing
Security Requirements
- Always call
completePayment()
to properly end sessions - Validate payment token format and integrity
- Log audit events while protecting sensitive data
Routes & Integration Checklist
Note: Backend routes in examples (e.g., /api/apple-pay/process-payment
) are illustrative; align with your service design while keeping frontend and backend consistent.
Integration Checklist
- Test successful payment workflows
- Test failure scenarios and error handling
- Verify proper
completePayment()
implementation - Confirm correct
tokenInfo
field structure - Test webhook notification processing
- Validate signature verification logic
Next Steps
After completing payment authorization, continue with the following flows:
- Complete Payment Flow - View end-to-end integration examples
- Troubleshooting - Common problem solutions
- Production Deployment - Configure production environment and monitoring
Prerequisites: Confirm completion of Merchant Validation and Session Initialization.