Apple Pay ™ Integation Guide
Accept payments with Apple Pay using the Ecart Pay SDK. As a supported Payment Service Provider (PSP), Ecart Pay handles merchant validation, token decryption, and payment processing — your integration is just a few lines of JavaScript.
Table of Contents
- Getting Started
- Apple Pay Policies & Terms
- Installation
- Quick Start
- Required Parameters
- Optional Parameters
- Supported Card Networks
- Merchant Capabilities
- Billing & Shipping Contact
- Handling the Payment Response
- Events
- Button Styles
- Cross-Browser Support
- Domain Verification
- Complete Example
- Testing
- Going to Production
- Resources
🚀 Getting Started
Prerequisites
Before integrating Apple Pay through the Ecart Pay SDK, ensure:
| Requirement | Description |
|---|---|
| Ecart Pay Account | Active merchant account with the card payment method enabled |
| HTTPS | Your website must be served over HTTPS |
| Domain Verification | Your domain must be verified with Apple (see Domain Verification) |
| Order ID | You can create orders via the Ecart Pay Orders API |
☝️ Apple Pay Policies & Terms
All merchants using Apple Pay through Ecart Pay must complete the following essential steps:
Comply with Apple Policies
- Follow the Apple Pay Acceptable Use Guidelines.
- Follow the Apple Pay Human Interface Guidelines.
- Accept the Apple Pay Web Merchant Terms and Conditions.
📦 Installation
Add the Ecart Pay SDK <script> tag to your HTML page:
<!-- Production Environment -->
<script src="https://ecartpay.com/sdk/pay.js"></script>
<!-- Sandbox Environment (For testing purposes) -->
<script src="https://sandbox.ecartpay.com/sdk/pay.js"></script>
NoteUse the sandbox version for development and testing. Switch to the production script only when you're ready to go live.
The SDK automatically loads the Apple Pay JS SDK when Pay.ApplePay.render() is called. This enables Apple Pay on all supported browsers, including Chrome and Firefox (via QR code on a nearby iPhone).
⚡ Quick Start
<div id="apple-pay-button"></div>
<script src="https://ecartpay.com/sdk/pay.js"></script>
<script>
// 1. Listen for events
Pay.ApplePay.on('ready', function () {
console.log('Apple Pay button is ready');
});
Pay.ApplePay.on('success', function (event) {
console.log('Payment successful:', event.detail);
if (event.detail.redirect_url) {
window.location.href = event.detail.redirect_url;
}
});
Pay.ApplePay.on('error', function (event) {
console.error('Error:', event.detail.message);
});
Pay.ApplePay.on('cancel', function () {
console.log('Payment cancelled by user');
});
// 2. Render the button
Pay.ApplePay.render({
container: '#apple-pay-button',
orderId: 'YOUR_ORDER_ID',
amount: 100.00,
currency: 'MXN',
countryCode: 'MX',
label: 'My Store',
});
</script>📋 Required Parameters
| Parameter | Type | Description |
|---|---|---|
container | string | CSS selector or DOM element where the Apple Pay button will be rendered |
orderId | string | The Ecart Pay order ID (obtained from the Orders API) |
amount | number | Total amount to charge |
currency | string | ISO 4217 currency code (e.g., MXN, USD) |
countryCode | string | ISO 3166-1 alpha-2 country code (e.g., MX, US) |
🧩 Optional Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
label | string | 'ecartpay' | Merchant display name on the payment sheet |
supportedNetworks | array | ['visa', 'masterCard', 'amex', 'discover'] | Card networks to accept |
merchantCapabilities | array | ['supports3DS'] | Payment capabilities |
totalType | string | 'final' | 'final' or 'pending' |
requiredBillingContactFields | array | — | Fields to request from billing contact |
requiredShippingContactFields | array | — | Fields to request from shipping contact |
shippingMethods | array | — | Available shipping options |
shippingType | string | — | 'shipping', 'delivery', 'storePickup', 'servicePickup' |
buttonStyle | string | 'black' | 'black', 'white', 'white-outline' |
buttonType | string | 'pay' | 'pay', 'buy', 'plain', 'check-out', 'donate' |
locale | string | — | Button language (e.g., 'en', 'es') |
width | string | '100%' | Button width (CSS value) |
height | string | '44px' | Button height (CSS value) |
borderRadius | string | '4px' | Corner radius (CSS value) |
applePayVersion | number | 3 | Apple Pay JS API version (3–14) |
onShippingMethodSelected | function | — | Callback for shipping method changes |
onShippingContactSelected | function | — | Callback for shipping contact changes |
🌐 Supported Card Networks
Define the card networks you accept using the supportedNetworks parameter:
| Network | Value |
|---|---|
| Visa | visa |
| Mastercard | masterCard |
| American Express | amex |
| Discover | discover |
Pay.ApplePay.render({
// ...
supportedNetworks: ['visa', 'masterCard', 'amex'],
});
ImportantNetwork values are case-sensitive for Apple Pay (e.g.,
masterCard, notMASTERCARD).
🔐 Merchant Capabilities
| Capability | Description |
|---|---|
supports3DS | Supports 3D Secure authentication (required) |
supportsDebit | Accepts debit cards |
supportsCredit | Accepts credit cards |
The supports3DS capability is always required by Apple Pay.
🏠 Billing & Shipping Contact
Request customer contact information from the Apple Pay payment sheet:
Pay.ApplePay.render({
// ...
requiredBillingContactFields: ['postalAddress', 'email', 'phone'],
requiredShippingContactFields: ['postalAddress', 'email', 'phone'],
});Available Contact Fields
| Field | Description |
|---|---|
postalAddress | Full postal address (street, city, state, zip) |
email | Email address |
phone | Phone number |
name | Full name |
How Contact Data Is HandledWhen the customer authorizes the payment, the SDK automatically sends the contact information to the Ecart Pay
POST /api/applepay/shipping-contactendpoint. This updates the order with the customer's address, email, and phone before processing the payment.
Shipping Methods
You can provide predefined shipping options:
Pay.ApplePay.render({
// ...
shippingType: 'shipping',
shippingMethods: [
{
label: 'Standard Shipping',
detail: '5-7 business days',
amount: '5.00',
identifier: 'standard',
},
{
label: 'Express Shipping',
detail: '1-2 business days',
amount: '15.00',
identifier: 'express',
},
],
});💸 Handling the Payment Response
The SDK handles the entire Apple Pay flow. You only need to listen for events.
Payment Flow
| Step | Description |
|---|---|
| 1 | Customer taps the Apple Pay button |
| 2 | Apple Pay payment sheet is displayed |
| 3 | Customer authenticates with Face ID, Touch ID, or passcode |
| 4 | Merchant validation — SDK calls POST /api/applepay/validate-merchant |
| 5 | Contact data — SDK sends shipping/billing contact to POST /api/applepay/shipping-contact |
| 6 | Payment — encrypted token sent to POST /api/process-payment |
| 7 | Ecart Pay decrypts, validates, and processes the transaction |
| 8 | SDK emits success or error event |
Pay.ApplePay.on('success', function (event) {
var result = event.detail;
console.log('Payment status:', result.status);
if (result.redirect_url) {
window.location.href = result.redirect_url;
}
});
Best PracticeAlways use the order status from the Orders API (
GET /api/orders/:id) as the source of truth for your business logic. Do not rely solely on the SDK event.
📡 Events
| Event | Description | event.detail |
|---|---|---|
ready | Button rendered. native indicates Safari native button | { native: boolean } |
unavailable | Apple Pay is not available for this account | { message: string } |
success | Payment processed successfully | { status, redirect_url } |
error | Error during initialization or payment | { message: string } |
cancel | Customer cancelled the payment sheet | {} |
Pay.ApplePay.on('ready', function (e) {
console.log('Native button:', e.detail.native);
});
Pay.ApplePay.on('unavailable', function (e) { /* hide section */ });
Pay.ApplePay.on('success', function (e) { /* redirect */ });
Pay.ApplePay.on('error', function (e) { /* show error */ });
Pay.ApplePay.on('cancel', function () { /* user dismissed */ });🎨 Button Styles
The SDK renders two types of buttons depending on the browser:
Native Button (Safari)
In Safari, the SDK renders the official Apple Pay button using the native -webkit-appearance: -apple-pay-button CSS property, which automatically follows Apple's brand guidelines.
Fallback Button (Chrome, Firefox, Edge)
In non-Safari browsers, the SDK renders a styled fallback button with the Apple logo and "Pay" text. If the native CSS property is not supported, the fallback is used automatically.
Style Options
| Style | Description |
|---|---|
black | Black background, white text and logo (default) |
white | White background, black text and logo |
white-outline | Transparent with border, black text and logo |
Pay.ApplePay.render({
// ...
buttonStyle: 'black',
buttonType: 'pay',
borderRadius: '8px',
height: '48px',
});🖥️ Cross-Browser Support
| Browser | Experience |
|---|---|
| Safari (macOS/iOS) | Native Apple Pay with Face ID, Touch ID, or passcode |
| Chrome | Apple Pay via QR code — scan with iPhone to authenticate |
| Firefox | Apple Pay via QR code — same cross-device flow |
| Edge | Apple Pay via QR code — same cross-device flow |
How It WorksThe SDK automatically loads the Apple Pay JS SDK which enables the QR code flow in non-Safari browsers. No additional configuration is required by the merchant.
🔒 Domain Verification
Apple Pay requires that your domain is verified before accepting payments.
How It Works
Apple verifies domain ownership by checking for a specific file at:
https://yourdomain.com/.well-known/apple-developer-merchantid-domain-association.txt
Steps
| Step | Action |
|---|---|
| 1 | Contact Ecart Pay support to register your domain with Apple Pay |
| 2 | Ecart Pay provides the apple-developer-merchantid-domain-association.txt file |
| 3 | Host the file at /.well-known/apple-developer-merchantid-domain-association.txt |
| 4 | Ensure the file is accessible over HTTPS without authentication or redirects |
ImportantThe domain verification file must be served with
Content-Type: text/plainand must be accessible at the exact path shown above. Each domain (including subdomains) requires its own verification.
🧪 Complete Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Apple Pay Checkout - Ecart Pay</title>
<style>
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #f5f5f5; }
.checkout { max-width: 480px; margin: 40px auto; padding: 24px; background: #fff; border-radius: 12px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
#apay-container { min-height: 48px; margin: 16px 0; }
.status { padding: 12px; border-radius: 8px; margin-top: 12px; display: none; font-size: 14px; }
.status.success { display: block; background: #d1fae5; color: #065f46; }
.status.error { display: block; background: #fee2e2; color: #991b1b; }
</style>
</head>
<body>
<div class="checkout">
<h2>Checkout</h2>
<p>Total: <strong>$100.00 MXN</strong></p>
<div id="apay-container"></div>
<div id="status" class="status"></div>
</div>
<script src="https://ecartpay.com/sdk/pay.js"></script>
<script>
var statusEl = document.getElementById('status');
Pay.ApplePay.on('success', function (event) {
statusEl.className = 'status success';
statusEl.textContent = 'Payment successful!';
if (event.detail.redirect_url) {
window.location.href = event.detail.redirect_url;
}
});
Pay.ApplePay.on('error', function (event) {
statusEl.className = 'status error';
statusEl.textContent = 'Error: ' + event.detail.message;
});
Pay.ApplePay.on('cancel', function () {
statusEl.className = 'status error';
statusEl.textContent = 'Payment cancelled.';
});
Pay.ApplePay.on('unavailable', function (event) {
statusEl.className = 'status error';
statusEl.textContent = event.detail.message;
});
// Replace YOUR_ORDER_ID with a real order ID from the Ecart Pay Orders API
Pay.ApplePay.render({
container: '#apay-container',
orderId: 'YOUR_ORDER_ID',
amount: 100.00,
currency: 'MXN',
countryCode: 'MX',
label: 'My Store',
buttonStyle: 'black',
buttonType: 'pay',
borderRadius: '8px',
supportedNetworks: ['visa', 'masterCard', 'amex'],
requiredShippingContactFields: ['postalAddress', 'email', 'phone'],
requiredBillingContactFields: ['postalAddress'],
});
</script>
</body>
</html>
NoteYou can copy and paste this into an
.htmlfile and run it locally to test. Remember to use HTTPS (Apple Pay requires it) and the sandbox SDK for testing.
🧪 Testing
Use the Sandbox environment for testing:
<script src="https://sandbox.ecartpay.com/sdk/pay.js"></script>Apple Pay Sandbox Testing
| Step | Action |
|---|---|
| 1 | Create a Sandbox Tester Account in Apple Developer |
| 2 | Add test cards to your sandbox Apple Pay wallet |
| 3 | Test on a device signed into the sandbox account |
Refer to the Apple Pay Sandbox Testing Guide for detailed instructions.
🚀 Going to Production
| Step | Action |
|---|---|
| 1 | Verify your production domain with Apple (see Domain Verification) |
| 2 | Switch to production SDK: <script src="https://ecartpay.com/sdk/pay.js"></script> |
| 3 | Verify your Ecart Pay account is active and card payment method is enabled |
| 4 | Test the complete flow on Safari (Mac/iOS), Chrome, and Firefox with real Apple Pay cards |
🔎 Resources
Apple Pay Documentation
| Resource | Link |
|---|---|
| Apple Pay on the Web | developer.apple.com/apple-pay/web |
| Apple Pay JS API Reference | Apple Pay JS API |
| Human Interface Guidelines | Apple Pay HIG |
| Acceptable Use Guidelines | AUG |
| Sandbox Testing | Testing Guide |
Ecart Pay Documentation
| Resource | Link |
|---|---|
| SDK JS Documentation | docs.ecartpay.com/docs/sdks |
| Orders API | docs.ecartpay.com/docs/orders |
| 3D Secure Flow | docs.ecartpay.com/docs/3d-secure |
Updated about 2 months ago