Direct API integration | Apple Pay payment

MoneyHash offers direct API integrations that allow you to integrate and pay using Apple Pay with minimal or zero hosted pages. To allow zero hosted pages, you must be a PCI-compliant MoneyHash enterprise customer.

After creating an intent for payment with use_direct_api flag, you can use use MoneyHash to process Apple Pay token that retrieved from Apple during the payment and pass it to MoneyHash to process it with your integrated providers .

Overview

Apple Pay direct API integration uses the same structure for our Payment direct API integration for how to get the intent details and proceed with the payment.

After creating an intent for payment with use_direct_api flag, You can set the intent selected method to Apple Pay using Pay with selected methods and specify apple pay as the selected method.

1. Creating a payment intent

curl --location --request POST 'https://web.moneyhash.io/api/v1.1/payments/intent/' \
--header 'X-Api-Key: YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data-raw '{"amount": 10, "amount_currency": "USD", "operation": "purchase", "use_direct_api": true}'
import requests

url = "https://moneyhash.io/api/v1.1/payments/intent/"
payload = {
    "amount": 50,
    "amount_currency": "USD",
    "operation": "purchase",
    "use_direct_api": True
}
headers = {
    'X-Api-Key': '<YOUR_API_KEY>',
    'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, json=payload)
print(response.text.encode('utf8'))

and the response would be

{
  "status": {
    "code": 200,
    "message": "success",
    "errors": []
  },
  "data": {
    "embed_url": "https://web.moneyhash.io/payments/embed/ePgw3gN/",
    "id": "ePgw3gN",
    "status": "UNPROCESSED"
  },
  "count": null,
  "next": null,
  "previous": null
}

You can also create your intent for Payment and you can specify apple method directly in the intent request by using "payment_method": "APPLE_PAY" Which will select apple pay as the method without the needs for creating the intent and update the method after that.

curl --location --request POST 'https://web.moneyhash.io/api/v1.1/payments/intent/' \
--header 'X-Api-Key: YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data-raw '{"amount": 10, "amount_currency": "USD", "payment_method": "APPLE_PAY", "operation": "purchase", "use_direct_api": true}'

import requests

url = "https://moneyhash.io/api/v1.1/payments/intent/"
payload = {
    "amount": 50,
    "amount_currency": "USD",
    "operation": "purchase",
    "use_direct_api": True
}
headers = {
    'X-Api-Key': '<YOUR_API_KEY>',
    'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, json=payload)
print(response.text.encode('utf8'))

let's grab the intent id from data.id and let's fetch the intent details

2. Getting intent details

curl --location --request GET 'https://web.moneyhash.io/api/v1.1/payments/external/intents/ePgw3gN/' \
--header 'X-Api-Key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' 
import requests

url = 'https://web.moneyhash.io/api/v1.1/payments/external/intent/ePgw3gN'
headers = {
    'X-Api-Key': '<YOUR_API_KEY>',
    'Content-Type': 'application/json'
}

response = requests.get(url, headers=headers)
print(response.json())

const fetch = require('node-fetch');

const url = 'https://web.moneyhash.io/api/v1.1/payments/external/intent/ePgw3gN';
const headers = {
  'X-Api-Key': '<YOUR_API_KEY>',
  'Content-Type': 'application/json'
};

fetch(url, {
  method: 'GET',
  headers: headers
})
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error(error));

and the response would be:

{
  "status": {
    "code": 200,
    "message": "success",
    "errors": []
  },
  "data": {
    "state": "METHOD_SELECTION",
    "state_details": {
      "payment_methods": [
        {
          "payment_method_name": "Cash Outlet",
          "has_customized_label": false,
          "payment_method": "CASH_OUTLET",
          "checkout_icons": [
            "https://web.moneyhash.io/static/images/checkout_icons/payat-checkout.svg"
          ],
          "confirmation_required": true,
          "use_for_express_checkout": false
        },
        {
          "payment_method_name": "Mobile Wallet",
          "has_customized_label": false,
          "payment_method": "MOBILE_WALLET",
          "checkout_icons": [
            "https://web.moneyhash.io/static/images/checkout_icons/Mobile_Wallet.svg"
          ],
          "confirmation_required": false,
          "use_for_express_checkout": false
        },
        {
          "payment_method_name": "Card",
          "has_customized_label": false,
          "payment_method": "CARD",
          "checkout_icons": [
            "https://web.moneyhash.io/static/images/checkout_icons/Visa.svg",
            "https://web.moneyhash.io/static/images/checkout_icons/Master_Card.svg"
          ],
          "confirmation_required": false,
          "use_for_express_checkout": false
        },
        {
          "payment_method_name": "Paypal",
          "has_customized_label": false,
          "payment_method": "PAYPAL",
          "checkout_icons": [
            "https://web.moneyhash.io/static/images/checkout_icons/Paypal.svg"
          ],
          "confirmation_required": true,
          "use_for_express_checkout": false
        },
        {
          "payment_method_name": "Cash On Delivery",
          "has_customized_label": false,
          "payment_method": "CASH_ON_DELIVERY",
          "checkout_icons": [
            "https://web.moneyhash.io/static/images/checkout_icons/Cash.svg"
          ],
          "confirmation_required": true,
          "use_for_express_checkout": false
        },
        {
          "payment_method_name": "M-Pesa",
          "has_customized_label": false,
          "payment_method": "M_PESA",
          "checkout_icons": [
            "https://web.moneyhash.io/static/images/checkout_icons/M-Pesa-icon.svg"
          ],
          "confirmation_required": false,
          "use_for_express_checkout": false
        },
        {
          "payment_method_name": "Mobile Money",
          "has_customized_label": false,
          "payment_method": "MOBILE_MONEY",
          "checkout_icons": [
            "https://web.moneyhash.io/static/images/checkout_icons/Mobile_Wallet.svg"
          ],
          "confirmation_required": false,
          "use_for_express_checkout": false
        },
        {
          "payment_method_name": "Crypto Wallet",
          "has_customized_label": false,
          "payment_method": "CRYPTO_WALLET",
          "checkout_icons": [
            "https://web.moneyhash.io/static/images/checkout_icons/crypto_method.svg"
          ],
          "confirmation_required": false,
          "use_for_express_checkout": false
        }
      ],
      "express_methods": [
        {
          "payment_method_name": "Google Pay",
          "has_customized_label": false,
          "payment_method": "GOOGLE_PAY",
          "checkout_icons": [
            "https://web.moneyhash.io/static/images/checkout_icons/Google%20Pay%20Icon.svg"
          ],
          "confirmation_required": false,
          "use_for_express_checkout": true
        }
      ],
      "saved_cards": [
        {
          "id": "zGgq4Lx",
          "brand": "MasterCard",
          "logo": "/static/images/card_icons/default.svg",
          "last4": "0022",
          "expiry_month": "03",
          "expiry_year": "25",
          "country": null,
          "requires_cvv": true
        }
      ],
      "customer_balances": [
        {
          "id": "SELFSERVE_WALLET",
          "balance": 0,
          "icon": "https://embed.moneyhash.io/assets/selfWalletIcon.767086fb.svg",
          "is_selected": false
        }
      ]
    },
    "selected_method": null,
    "intent": {
      "id": "ePgw3gN",
      "status": "UNPROCESSED",
      "amount": {
        "value": "10.00USD",
        "currency": "USD",
        "formatted": 10
      },
      "expiration_date": null,
      "is_live": false
    },
    "transaction": null
  },
  "count": 1,
  "next": null,
  "previous": null
}

๐Ÿ“˜

Note that the state here is METHOD_SELECTION which means we need to render the available methods to users to select the method they want to proceed wi

3.Update selected method

If you created the intent without specifying APPLE_PAY method ori your customer selected any other method, then you can update the intent selected method by using

curl --location --request POST 'https://web.moneyhash.io/api/v1.1/external/payments/intents/ePgw3gN/update-method/' \
--header 'X-Api-Key: <YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data-raw '{"payment_method": "APPLE_PAY"}'
import requests

url = 'https://web.moneyhash.io/api/v1.1/external/payments/intents/ePgw3gN/update-method/'
headers = {
    'X-Api-Key': '<YOUR_API_KEY>',
    'Content-Type': 'application/json'
}
payload = {
    'payment_method': 'CARD'
}

response = requests.post(url, headers=headers, json=payload)
print(response.json())

const fetch = require('node-fetch');

const url = 'https://web.moneyhash.io/api/v1.1/external/payments/intents/ePgw3gN/update-method/';
const headers = {
  'X-Api-Key': '<YOUR_API_KEY>',
  'Content-Type': 'application/json'
};
const payload = {
  payment_method: 'CARD'
};

fetch(url, {
  method: 'POST',
  headers: headers,
  body: JSON.stringify(payload)
})
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error(error));

After selecting Apple Pay as method in your intent, You will receive NATIVE_PAY state in the response of Get intent details or the response of update selected method and the method type will be APPLE_PAY

๐Ÿ“˜

Native pay data

native pay data differs based on the selected payment method. native_pay_data always contains all required information to initialize your native payment.

{
  "status": {
    "code": 200,
    "message": "success",
    "errors": []
  },
  "data": {
    "state": "NATIVE_PAY",
    "state_details": {
      "method_type": "APPLE_PAY",
      "native_pay_data": {
        "merchant_id": "Your configured merchent id with be here started with merchant.",
        "country_code": "AE",
        "amount": 50,
        "currency_code": "USD"
      }
    },
    "intent": {
      "id": "XZOqML8",
      "status": "UNPROCESSED",
      "amount": {
        "value": "50.00USD",
        "currency": "USD",
        "formatted": 50
      },
      "expiration_date": null,
      "is_live": false
    },
    "selected_method": "APPLE_PAY",
    "transaction": null
  },
  "count": 1,
  "next": null,
  "previous": null
}

4. Proceed with Apple Pay token

After getting the above response, you need to display Apple Pay natively within your application, and after a successful transaction, you need to get Apple Pay token as following

    func paymentAuthorizationController(
        _ controller: PKPaymentAuthorizationController,
        didAuthorizePayment payment: PKPayment,
        handler completion: @escaping (PKPaymentAuthorizationResult) -> Void
    ) {
        let paymentToken = String(data: payment.token.paymentData, encoding: .utf8)
        
        // Now you need to send the paymentToken to receipt endpoint to process it
    }

๐Ÿ“˜

Native pay data

MoneyHash receipt endpoint expect a certain type of information, in the case of Apple Pay, we expect PaymentData to be submitted as a receipt.

Now you need to submit the Apple Pay receipt to the following endpoint:

POST https://web.moneyhash.io/api/v1.1/payments/intent/<intent_id>/receipt/
{
	"receipt": "eyJzaWduYXR1cmUiID0gIkFoaHEwbmFxaG01ci8wSUNuYk9hVThCeVBLNkRja2ZsanRCMDNnZUh4dk0ybEVjVkdqK2NVM1lnWGZ0RkZCZ2lFYkR1NGdoYXFVWFRqRzlpc25Zeit6VWFhTXRUZDJ6YnNLbFhIMitzYm1ZaC9tY2M2eWt3dVFkaFZsOWZKYkxNaFVXWHNTUlIxVlVjQlE4TkxjVGg5ZHNXOTVTREcxdG9DQk45cWM0L01CZlVBQUFEVnpDQ0ExTXdnZ0k3b0FNQ0FRSUNDQnVwNCtQQWhtL0xNQTBHQ1NxR1NJYjNEUUVCQlFVQU1IOHhDekFKQmdOVkJBWVRBbFZUTVJNd0VRWURWUVFLREFwQmNIQnNaU0JKYm1NdU1TWXdKQVlEVlFRTERCMUJjSEJzWlNCRFpYSjBhV1pwWTJGMGFXOXVJRUYxZEdodmNtbDBlVEV6TURFR0ExVUVBd3dxUVhCd2JHVWdhVlIxYm1WeklGTjBiM0psSUVObGNuUnBabWxqWVhScGIyNGdRWFYwYUc5eWFYUjVNQjRYRFRFME1EWXdOekF3TURJeU1Wb1hEVEUyTURVeE9ERTRNekV6TUZvd1pERWpNQ0VHQTFVRUF3d2FVSFZ5WTJoaGMyVlNaV05sYVhCMFEyVnlkR2xtYVdOaGRHVXhHekFaQmdOVkJBc01Fa0Z3Y0d4bElHbFVkVzVsY3lCVGRHOXlaVEVUTUJFR0ExVUVDZ3dLUVhCd2JHVWdTVzVqTGpFTE1Ba0dBMVVFQmhNQ1ZWTXdnWjh3RFFZSktvWklodmNOQVFFQkJRQURnWTBBTUlHSkFvR0JBTW1URXVMZ2ppbUx3Ukp4eTFvRWYwZXNVTkRWRUllNndEc25uYWwxNGhOQnQxdjE5NVg2bjkzWU83Z2kzb3JQU3V4OUQ1NTRTa01wK1NheWc4NGxUYzM2MlV0bVlMcFduYjM0bnF5R3g5S0JWVHk1T0dWNGxqRTFPd0Mrb1RuUk0rUUxSQ21lTnhNYlBaaFM0N1QrZVp0REVoVkI5dXNrMytKTTJDb2dmd283QWdNQkFBR2pjakJ3TUIwR0ExVWREZ1FXQkJTSmFFZU51cTlEZjZaZk42OEZlK0kydTIyc3NEQU1CZ05WSFJNQkFmOEVBakFBTUI4R0ExVWRJd1FZTUJhQUZEWWQ2T0tkZ3RJQkdMVXlhdzdYUXd1UldFTTZNQTRHQTFVZER3RUIvd1FFQXdJSGdEQVFCZ29xaGtpRzkyTmtCZ1VCQkFJRkFEQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUFlYUpWMlU1MXJ4ZmNxQUFlNUMyL2ZFVzhLVWw0aU80bE11dGE3TjZYelAxcFpJejFOa2tDdElJd2V5Tmo1VVJZSEsrSGpSS1NVOVJMZ3VObDBua2Z4cU9iaU1ja3dSdWRLU3E2OU5JbnJaeUNENjZSNEs3N25iOWxNVEFCU1NZbHNLdDhvTnRsaGdSLzFralNTUlFjSGt0c0RjU2lRR0tNZGtTbHA0QXlYZjd2bkhQQmU0eUN3WVYyUHBTTjA0a2JvaUozcEJseHNHd1YvWmxMMjZNMnVlWUhLWUN1WGhkcUZ3eFZnbTUyaDNvZUpPT3Qvdlk0RWNRcTdlcUhtNm0wM1o5YjdQUnpZTTJLR1hIRG1PTWs3dkRwZU1WbExEUFNHWXoxK1Uzc0R4SnplYlNwYmFKbVQ3aW16VUtmZ2dFWTd4eGY0Y3pmSDB5ajV3TnpTR1RPdlE9PSI7ICJwdXJjaGFzZS1pbmZvIiA9ICJld29KSW05eWFXZHBibUZzTFhCMWNtTm9ZWE5sTFdSaGRHVXRjSE4wSWlBOUlDSXlNREUxTFRFeExUSXpJREE0T2pNeU9qSTNJRUZ0WlhKcFkyRXZURzl6WDBGdVoyVnNaWE1pT3dvSkluVnVhWEYxWlMxcFpHVnVkR2xtYVdWeUlpQTlJQ0psTkRjME1qVmtaamRtWWpaaFlqaGpNMk0zWlRVM016QmpNMkUzWldJMVlqWTFOak00TWpOa0lqc0tDU0p2Y21sbmFXNWhiQzEwY21GdWMyRmpkR2x2YmkxcFpDSWdQU0FpTVRBd01EQXdNREU0TVRRNU1qVTFOeUk3Q2draVluWnljeUlnUFNBaU15STdDZ2tpZEhKaGJuTmhZM1JwYjI0dGFXUWlJRDBnSWpFd01EQXdNREF4T0RFME9USTFOVGNpT3dvSkluRjFZVzUwYVhSNUlpQTlJQ0l4SWpzS0NTSnZjbWxuYVc1aGJDMXdkWEpqYUdGelpTMWtZWFJsTFcxeklpQTlJQ0l4TkRRNE1qazJNelEzTVRNNElqc0tDU0oxYm1seGRXVXRkbVZ1Wkc5eUxXbGtaVzUwYVdacFpYSWlJRDBnSWpWRE1qYzFRalZCTFRORk5qWXROREF5TmkwNU5USXpMVGcwTlVJeU1qVTNOVFZHUXlJN0Nna2ljSEp2WkhWamRDMXBaQ0lnUFNBaWNIVnlZMmhoYzJWeUxtTnZibk4xYldGaWJHVkdaV0YwZFhKbElqc0tDU0pwZEdWdExXbGtJaUE5SUNJeE1EWXhOVFUzTkRnMElqc0tDU0ppYVdRaUlEMGdJbU52YlM1bGN5NVFkWEpqYUdGelpYSWlPd29KSW5CMWNtTm9ZWE5sTFdSaGRHVXRiWE1pSUQwZ0lqRTBORGd5T1RZek5EY3hNemdpT3dvSkluQjFjbU5vWVhObExXUmhkR1VpSUQwZ0lqSXdNVFV0TVRFdE1qTWdNVFk2TXpJNk1qY2dSWFJqTDBkTlZDSTdDZ2tpY0hWeVkyaGhjMlV0WkdGMFpTMXdjM1FpSUQwZ0lqSXdNVFV0TVRFdE1qTWdNRGc2TXpJNk1qY2dRVzFsY21sallTOU1iM05mUVc1blpXeGxjeUk3Q2draWIzSnBaMmx1WVd3dGNIVnlZMmhoYzJVdFpHRjBaU0lnUFNBaU1qQXhOUzB4TVMweU15QXhOam96TWpveU55QkZkR012UjAxVUlqc0tmUT09IjsiZW52aXJvbm1lbnQiID0gIlNhbmRib3giOyJwb2QiID0gIjEwMCI7InNpZ25pbmctc3RhdHVzIiA9ICIwIjt9"
}

After successful processing for the token, MoneyHash will return the intent state and the information in the response that contains the current Intent state and all information that we need to get about your intent.

๐Ÿ“˜

Certificates management

When utilizing direct API integration with MoneyHash, it's important to note that the responsibility for managing certificates lies with your side.
MoneyHash will not be involved in the management of any certificates. Instead, you are required to handle the entire certificate management process, including uploading and handling it. This process should be executed through your provider and Apple Pay dashboard.