Apple Pay payment

Direct Apple Pay Payment allows merchants to process Apple Pay transactions directly via a server-to-server connection. This integration enables merchants to handle the Apple Pay payment token securely on their backend without relying on the hosted checkout interface.

Use case A typical scenario involves collecting the Apple Pay token on the frontend (e.g., a website or mobile app) and securely transmitting it—along with the transaction session_id and amount—to this API.

This approach provides merchants with more control over their transaction flow, custom logic, and integration with internal systems while ensuring full PCI and Apple Pay compliance.

Before you can use the Submit Direct Apple Pay Payment API, ensure the following prerequisites are met:

  1. Apple Pay integration is implemented on your frontend to collect the payment token.

  2. A valid session_id is created using the Checkout API, which generates a unique session_id.

  3. The merchant has a configured Payment Gateway pg_code supporting Apple Pay transactions.

  4. The API must be accessed through HTTPS to ensure end-to-end encryption.

This API uses Basic Authentication. For more details about basic authentication, please check here.

The following permissions are required to use this API:

  • Payment Processing: The user or service account must have permission to initiate payment requests.

  • Session Access: The merchant must have valid access to the session_id created via the Checkout API.

  • Gateway Access: The configured payment gateway must be active and support Apple Pay transactions.

  1. Frontend collection: The customer completes the checkout using Apple Pay on your website or mobile app. The frontend obtains a valid Apple Pay token containing encrypted payment data.

  2. Server submission: Your backend sends a POST request to the Submit Direct Apple Pay Payment API, including:

    • payload: Structured token with encryption data and payment method details.

    • session_id: the transaction session identifier

    • amount: the payment amount

    • Optional: customer and address details

  3. Gateway processing: Ottu forwards the transaction details to the configured payment gateway.

  4. Response handling: The response returns the final payment details, including transaction state, paid amount, gateway response, and message status.

Use this response to update your order or transaction status.

Submit a direct Apple Pay payment (Merchant API)

post

Allows merchants to submit an Apple Pay payment directly via server-to-server integration. This endpoint requires private key authentication and expects a valid Apple Pay token structure in the request payload under payload.

Typical use case: The merchant collects the Apple Pay token on their frontend and sends it to this endpoint along with session and amount information.

Authorizations
Body
pg_codestring | nullOptional

The unique pg_code used for this payment instrument.

session_idstringRequired

A unique identifier for the payment transaction (session).

Responses
200Success
application/json
post
/b/pbl/v2/payment/apple-pay/
POST /b/pbl/v2/payment/apple-pay/ HTTP/1.1
Host: sandbox.ottu.net
Authorization: Basic username:password
Content-Type: application/json
Accept: */*
Content-Length: 320

{
  "payload": {
    "paymentData": {
      "version": "text",
      "data": "text",
      "signature": "text",
      "header": {
        "ephemeralPublicKey": "text",
        "wrappedKey": "text",
        "publicKeyHash": "text",
        "transactionId": "text"
      }
    },
    "paymentMethod": {
      "displayName": "text",
      "network": "text",
      "type": "text"
    },
    "transactionIdentifier": "text"
  },
  "pg_code": null,
  "session_id": "text"
}
{
  "pg_params": {
    "auth_code": null,
    "card_type": null,
    "card_holder": null,
    "cardholder_email": null,
    "card_expiry_month": null,
    "card_expiry_year": null,
    "full_card_expiry": null,
    "card_number": null,
    "card_issuer": null,
    "ref": null,
    "result": null,
    "track_id": null,
    "post_date": null,
    "transaction_id": null,
    "payment_id": null,
    "pg_message": null,
    "receipt_no": null,
    "transaction_no": null,
    "decision": null,
    "card_expiry": null,
    "card_details": null,
    "dcc_payer_amount": null,
    "dcc_payer_currency": null,
    "dcc_payer_exchange_rate": null,
    "rrn": null
  },
  "agreement": {
    "id": "text",
    "amount_variability": "fixed",
    "start_date": "2025-10-17",
    "expiry_date": "2025-10-17",
    "max_amount_per_cycle": "text",
    "cycle_interval_days": 1,
    "total_cycles": 1,
    "frequency": "irregular",
    "type": "recurring",
    "seller": {
      "name": "text",
      "short_name": "text",
      "category_code": "text"
    }
  },
  "amount": "text",
  "amount_details": {
    "currency_code": "text",
    "amount": "text",
    "total": "text",
    "fee": "text",
    "exchange_rate": "text"
  },
  "capture_delivery_address": true,
  "capture_delivery_location": true,
  "card_acceptance_criteria": {
    "min_expiry_time": 1
  },
  "currency_code": "text",
  "customer_address_city": "text",
  "customer_address_country": "text",
  "customer_address_line1": "text",
  "customer_address_line2": "text",
  "customer_birthdate": null,
  "customer_address_postal_code": "text",
  "customer_address_state": "text",
  "customer_email": "text",
  "customer_first_name": "text",
  "customer_id": "text",
  "customer_last_name": "text",
  "customer_phone": "text",
  "extra": null,
  "fee": "text",
  "gateway_account": "text",
  "gateway_name": "text",
  "gateway_response": {
    "ANY_ADDITIONAL_PROPERTY": "anything"
  },
  "initiator": {
    "id": 1,
    "first_name": "text",
    "last_name": "text",
    "username": "text",
    "email": "name@gmail.com",
    "phone": "text"
  },
  "is_sandbox": true,
  "message": "text",
  "order_no": null,
  "paid_amount": 1,
  "payment_type": "one_off",
  "reference_number": "text",
  "refunded_amount": 1,
  "remaining_amount": 1,
  "result": "pending",
  "session_id": "text",
  "settled_amount": 1,
  "signature": "text",
  "state": "text",
  "token": {
    "brand": null,
    "customer_id": "text",
    "cvv_required": true,
    "expiry_month": "text",
    "expiry_year": "text",
    "is_expired": true,
    "is_preferred": true,
    "name_on_card": null,
    "number": null,
    "pg_code": "text",
    "pg_name": "knet",
    "token": "text",
    "agreements": null
  },
  "transaction_log_id": null,
  "timestamp_utc": "2025-10-17T23:25:46.758Z",
  "transactions": [
    {
      "amount": "text",
      "currency_code": "text",
      "order_no": null,
      "session_id": "text",
      "state": "paid"
    }
  ],
  "voided_amount": 1
}

Endpoint

POST /merchant/v1/applepay/direct-payment/

Headers

Key
Value

Content-Type

application/json

Authorization

Basic <base64(client_id:client_secret)>


Request Body Example

{
  "pg_code": "apple_pg_001",
  "session_id": "1f72ac4b-098b-4a65-8e29-0cc2023b22ef",
  "payload": {
    "data": "Encrypted Apple Pay token data",
    "signature": "MEQCID3e...",
    "header": {
      "ephemeralPublicKey": "MFkwEwYHKoZIzj0CAQYIKo...",
      "publicKeyHash": "uKxZ1l...",
      "transactionId": "b14b5a..."
    }
  },
  "amount": "100.00",
  "currency_code": "USD",
  "customer_email": "customer@example.com",
  "customer_first_name": "John",
  "customer_last_name": "Doe",
  "customer_id": "cust_10023",
  "payment_type": "one_off"
}

Successful Response Example

{
  "result": "success",
  "message": "Payment processed successfully",
  "pg_params": {
    "transaction_id": "tx_728193",
    "auth_code": "A7G93H",
    "status": "Approved"
  },
  "amount": "100.00",
  "currency_code": "USD",
  "paid_amount": "100.00",
  "timestamp_utc": "2025-10-08T14:33:12Z",
  "session_id": "1f72ac4b-098b-4a65-8e29-0cc2023b22ef",
  "state": "completed",
  "signature": "f1ab9d62e4c..."
}

Error Response Example

{
  "result": "failed",
  "message": "Invalid Apple Pay token",
  "state": "error"
}

  1. Token Security: Always handle Apple Pay tokens securely. Process them immediately and avoid storing raw token data.

  2. Validation: Verify that the session_id corresponds to a valid checkout session before submission.

  3. Error Handling: Implement retry logic for network errors, but avoid retrying failed or declined transactions automatically.

  4. Currency and Amount Consistency: Ensure the currency and amount match the values displayed to the customer during checkout to prevent mismatched payments.

  5. Logging and Signature Verification: Log API responses and verify the signature field to ensure data integrity.

  6. Test Thoroughly: Use sandbox mode for initial integration to confirm the Apple Pay token exchange and gateway communication work as expected.

Q1: Can I use this API without the Checkout API? No. You must first create a transaction session via the Checkout API, which provides the session_id used here.

Q2: What happens if the Apple Pay token expires before submission? The payment will fail. Tokens should be submitted immediately after being generated by the Apple Pay sheet.

Q3: Is this API suitable for recurring or auto-debit payments? Yes. Use the payment_type as auto_debit, and ensure both agreement and customer_id are provided.

Q4: What is the difference between this API and the hosted checkout method? This API allows server-to-server processing, giving merchants more flexibility and control, while hosted checkout handles token submission via Ottu’s front-end interface.

Q5: How can I test this integration? Use sandbox credentials and test Apple Pay tokens to simulate different transaction outcomes before going live.

Last updated