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 isMETHOD_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.
Updated about 1 year ago