Paga Apple tramite Widget
In questa pagina
Questa guida ti accompagna attraverso l'integrazione Paga di Apple utilizzando i SDK DEUNA
| Pagamento Widget | Vault di pagamento | |
|---|---|---|
| Cosa fa** | Mantiene il checkout completo: UI, elaborazione dei pagamenti e conferma | Tokenizes la carta solo — restituisce un card id per voi da usare |
| Chi elabora l'acquisto | DEUNA (internalmente) | (tramite l'API di acquisto dal vostro backend) |
| Pulsante Apple Pay | Rendered all'interno dell'iframe di DEUNA | Rendered da voi, nel vostro UI |
| Metodo SDK | initPaymentWidget | initElements({ types: ['APPLE_PAY'] }) |
| Usa quando | Vuoi un'esperienza di checkout a drop-in | È necessario controllare il flusso di pagamento o vuole memorizzare la carta per più tardi |
1. Prerequisiti#
Prima di iniziare, assicurarsi che i seguenti siano in posizione:
| Requisito | Note |
|---|---|
| Account DEUNA | Account attivo del commerciante nel Dashboard DEUNA. |
publicApiKey | Chiave API pubblica rilasciata da DEUNA. Obbligatorio DeunaSDK.initialize. |
orderToken | Generato sul tuo backend tramite l'API DEUNA Orders. Richiesto di avviare un pagamento. |
userToken (opzionale) | Richiesto solo quando si desidera gettare la carta contro un noto utente DEUNA. |
| dominio HTTPS | Apple Pay richiede che la pagina venga servita su HTTPS. localhost è consentito solo per lo sviluppo. |
| Requisiti di compatibilità | Fare riferimento al funzionario Paga Apple sul Web e Applicazione Apple Pay documentazione. Apple Pay richiede Safari su iOS 10+ o macOS 10.12+; su browser non sicuri (Chrome, Edge, Firefox), è disponibile un flusso di codice QR per gli utenti con un iPhone che esegue iOS 18 o versioni successive. |
1.1. Verifica del dominio (richiesto per entrambi i percorsi)
Ogni dominio che rende un pulsante Apple Pay — sia tramite il Payment Widget o il Vault — deve essere registrato con Apple tramite DEUNA. Questo vale per i domini di produzione e per qualsiasi ambiente di messa in scena o di anteprima.
Passo
- Ottenere il file di associazione di dominio dal Dashboard DEUNA (o da Apple Pay se si utilizza il proprio ID commerciante). Il file è tipicamente chiamato
apple-developer-merchantid-domain-association(non estensione) o.txt. - Host il file invariato a:
Assicurarsi:Plain text
https://<your-domain>/.well-known/apple-developer-merchantid-domain-association- La risposta è servita oltre HTTPS.
Content-Typeètext/plain; charset=utf-8.- Niente redirect, niente muro auth, no 404. La risposta deve essere
200 OK.
- Verificare il dominio nel Dashboard DEUNA (o portale Apple Pay Developer). Apple cercherà il file dal server; se corrisponde, il dominio è registrato.
- Ripetizione per dominio. Ogni hostname che carica il widget (ad es.
checkout.mystore.com,staging.mystore.com) deve servire il file e essere registrato separatamente.
implementazione di riferimento (Next.js - Esempio)
Questo repository implementa già l'endpoint di verifica. Due cose sono collegate:
next.config.js — riscrive sia il canonico che .txt percorsi per un percorso API:
async rewrites() {
return [
{
source: '/.well-known/apple-developer-merchantid-domain-association',
destination: '/api/apple-verification',
},
{
source: '/.well-known/apple-developer-merchantid-domain-association.txt',
destination: '/api/apple-verification',
},
];
}src/pages/api/apple-verification.ts — restituisce il contenuto del file come text/plain:
import { NextApiRequest, NextApiResponse } from 'next';
export default function domainVerification(
_req: NextApiRequest,
res: NextApiResponse,
) {
const fileContents = process.env.NEXT_PUBLIC_APPLE_VALIDATION_CONTENT_FILE;
res.setHeader('Content-Type', 'text/plain; charset=utf-8');
res.status(200).send(fileContents);
}Il contenuto del file viene memorizzato in una variabile di ambiente (NEXT_PUBLIC_APPLE_VALIDATION_CONTENT_FILE) in modo che possano essere ruotati per ambiente senza un cambio di codice.
Come verificare che funziona
curl -i https://<your-domain>/.well-known/apple-developer-merchantid-domain-associationconst response = await fetch("https://<your-domain>/.well-known/apple-developer-merchantid-domain-association", {
method: "GET"
});
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
const data = await response.json();import requests
response = requests.request(
"GET",
"https://<your-domain>/.well-known/apple-developer-merchantid-domain-association",
)
response.raise_for_status()
data = response.json()<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://<your-domain>/.well-known/apple-developer-merchantid-domain-association",
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => true
]);
$response = curl_exec($curl);
curl_close($curl);import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://<your-domain>/.well-known/apple-developer-merchantid-domain-association"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> response = HttpClient.newHttpClient().send(
request, HttpResponse.BodyHandlers.ofString()
);
System.out.println(response.body());
}
}package main
import (
"fmt"
"io"
"net/http"
)
func main() {
request, err := http.NewRequest("GET", "https://<your-domain>/.well-known/apple-developer-merchantid-domain-association", nil)
if err != nil { panic(err) }
response, err := http.DefaultClient.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, _ := io.ReadAll(response.Body)
fmt.Println(string(body))
}Aspettatevi:
- HTTP
200 OK Content-Type: text/plain; charset=utf-8- Un corpo che inizia con
7B22...(il blob di Apple)
2. Integrazioni#
Assicurarsi di seguire la guida di avvio per i nostri SDKs a seconda della vostra integrazione specifica:
2.1. Widget di pagamento
Particolarità di pagamento Apple
- Non è necessaria alcuna configurazione in codice. Apple Pay è abilitato o disabilitato dal Dashboard DEUNA. Se il commerciante ha attivato e il dispositivo dell'utente lo supporta, il pulsante appare automaticamente.
userTokenè facoltativo — solo necessario quando si desidera associare il pagamento a un account utente DEUNA conosciuto.- I widget standard callbacks (
onSuccess,onError,onClosed,onPaymentProcessing) lavorare allo stesso modo di altri metodi di pagamento.
Quando hai bisogno di getWalletsDisponibile nel Widget di pagamento?
Se si apre il widget con tutti i metodi di pagamento abilitati, non è necessario chiamare questo metodo — DEUNA rende il selettore del metodo di pagamento (compresi i pulsanti del portafoglio) e risolve la disponibilità internamente.
Hai solo bisogno di te. getWalletsAvailable quando si visualizza il proprio pulsante Apple Pay al di fuori del selettore e utilizzare Payment Widget in modalità standalone per saltare direttamente in quel metodo di pagamento. In questo caso, chiamalo in anticipo per decidere se mostrare il pulsante.
const { DeunaSDK } = window; // from https://cdn.deuna.io/web-sdk/v1.6/index.js
await DeunaSDK.initialize({
env: 'sandbox',
publicApiKey: '<YOUR_PUBLIC_API_KEY>',
});
// If Apple Pay is available, it should return it within an array, such as: ["APPLE_PAY"]
const available = await DeunaSDK.getWalletsAvailable();
if (available.includes('APPLE_PAY')) {
// Render button for Apple Pay and append a listener (EXAMPLE)
btn.addEventListener('click', () => {
DeunaSDK.initPaymentWidget({
orderToken: '<order-token>', // REQUIRED
paymentMethods: [
{
paymentMethod: 'wallet',
processors: ['apple_pay'],
},
], // In case only the specific payment method is to be used
callbacks: {
onSuccess: (order) => {
console.log('Payment completed:', order);
},
onError: (error) => {
console.error('Payment failed:', error.metadata.message);
},
onClosed: (action) => {
console.log('Widget closed:', action);
},
},
});
});
} else {
console.error('Apple Pay is not available on this device.');
}2.2. Vault di pagamento
SDK Web
Lasciare che il Web SDK risolva le credenziali di Apple Pay dal backend DEUNA utilizzando il vostro publicApiKey e (opzionale) un orderToken.
Per maggiori informazioni controllare il getWalletsAvailable documentation.
const { DeunaSDK } = window; // from https://cdn.deuna.io/web-sdk/v1.6/index.js
await DeunaSDK.initialize({
env: 'sandbox',
publicApiKey: '<YOUR_PUBLIC_API_KEY>',
});
// If Apple Pay is available, it should return it within an array, such as: ["APPLE_PAY"]
const available = await DeunaSDK.getWalletsAvailable();
if (available.includes('APPLE_PAY')) {
// Render button for Apple Pay and append a listener (EXAMPLE)
btn.addEventListener('click', () => {
deuna.initElements({
types: [{ name: 'APPLE_PAY' }],
orderToken: '<order-token>', // REQUIRED FOR MERCHANTS
userInfo: {
email: '<email>',
firstName: '<firstName>',
lastName: '<lastName>',
},
callbacks: {
// Called after user approves the Google Pay sheet.
// Send the token to your backend, return the result.
onSuccess: async (payload) => {
const cardId = payload.data.id;
// use the cardId to process payment
},
onError: (error) => {
console.error('Payment failed:', error.metadata.message);
},
},
});
});
} else {
console.error('Apple Pay is not available on this device.');
}SDK iOS
Prerequisiti del portafoglio di Paga di Mele (iOS)
Per utilizzare Apple Pay Wallet con SDK su iOS, assicurarsi che tutte le seguenti siano configurate correttamente.
-
Impostazione App e Team
- La tua app deve essere firmata con un Team di sviluppo Apple che ha Apple Pay abilitato.
- L'obiettivo PRODUCT_BUNDLE_IDENTIFIER deve corrispondere App ID configurato in Apple Developer.
- L'app deve essere installata su un dispositivo iOS reale (Apple Pay non funziona completamente in simulatore).
-
Impostazione ID Merchant
- Creare o utilizzare un ID Merchant in Apple Developer (esempio: mercanti.test.deuna.dev.pay).
- Assegnare che ID Merchant all'App ID dell'app sotto Identifiers > App ID > Apple Pay.
- In Xcode, abilitare la registrazione e le capacità > Apple Pay e selezionare lo stesso ID Merchant.
-
Certificati richiesti
Per l'ID Merchant utilizzato dalla SDK, è necessario avere:- Certificato di elaborazione pagamento Apple Pay (richiesto per l'elaborazione in-app di Apple Pay token).
-
Provvedimenti dei profili
- Rigenerare i profili di provisioning dopo aver cambiato le funzionalità Apple Pay o le assegnazioni di Merchant ID.
- Reinstallare l'app dopo le modifiche del profilo/capabilità (Clean Build Folder + delete app dal dispositivo + reinstall).
-
SDK/richiedi coerenza backend
-
L'ID Merchant restituito da credenziali backend (external merchant id) deve esattamente corrispondere all'ID Merchant abilitato nell'app.
-
Il flusso di portafoglio SDK dovrebbe includere il contesto utente (userInfo) quando richiesto dal tuo backend per restituire userToken e userId.
-
Se manca l'utenteToken/userId, la tokenizzazione può fallire anche se Apple Pay UI si apre.
-
Passo 1 — Controllare la disponibilità Chiamare getWalletsAvailable() una volta prima della fase di pagamento. L'SDK convalida sia la configurazione del commerciante DEUNA che la disponibilità di Apple Pay sul dispositivo.
import DeunaSDK
let deunaSDK = DeunaSDK(
environment: .sandbox,
publicApiKey: "YOUR_PUBLIC_API_KEY"
)
deunaSDK.getWalletsAvailable(
params: GetWalletsAvailableParams(
orderToken: "<order-token>", // optional at this stage
userInfo: DeunaSDK.UserInfo(
email: "user@example.com",
firstName: "Jane",
lastName: "Doe"
) // recommended for wallet auth flows
)
) { wallets, error in
if let error = error {
// handle fetch error
return
}
let applePayAvailable = wallets.contains(.applePay)
// show or hide your Apple Pay button based on applePayAvailable
}getWalletsAvailable() memorizza il risultato. Le chiamate successive ritornano immediatamente i portafogli cache, quindi è sicuro chiamare su ogni carico dello schermo.
Passo 2 — Lanciare Apple Pay Quando l'utente tocca il pulsante Apple Pay, chiama initElements con APPLE PAY come tipo. Il SDK fetches ordinazione credenziali e lancia il foglio di Apple Pay nativo.
deunaSDK.initElements(
userToken: "YOUR_ORDER_TOKEN", // required for apple pay wallet
callbacks: ElementsCallbacks(
onSuccess: { payload in
// payload contains tokenized card data
},
onError: { error in
// error.metadata?.code / message
},
onClosed: { _ in
// user dismissed the sheet
},
onEventDispatch: nil
),
closeEvents: [],
userInfo: DeunaSDK.UserInfo(
email: "user@example.com",
firstName: "Jane",
lastName: "Doe"
),
styleFile: nil,
types: [["name": "APPLE_PAY"]],
language: nil,
orderToken: "<order-token>",
widgetExperience: nil,
behavior: nil,
fraudCredentials: nil,
customUserAgent: nil,
domain: nil
)SDK React Native
Utilizzare questo percorso quando si desidera rendere un foglio di Apple Pay nativo direttamente, senza un WebView. Il SDK controlla la disponibilità del dispositivo, fetches Apple Pay credenziali dal backend DEUNA e lancia il foglio di pagamento. Il risultato è un carico di pagamento carta tokenizzata consegnato al vostro callback suSuccess.
Prerequisiti:
- Abilitare la funzionalità Apple Pay nel vostro target app (Xcode → target → Signing & Capabilities → + Capability → Apple Pay).
- Aggiungi il tuo ID Merchant sotto quella capacità (ad esempio, mercante.io.your-domain.com).
- Lo stesso ID Merchant deve essere restituito dalle credenziali DEUNA (external merchant id). Confermalo con il tuo team di account DEUNA.
- In Portale degli sviluppatori Apple, che Merchant ID deve avere un certificato attivo di elaborazione dei pagamenti di Apple Pay.
- Dopo qualsiasi funzionalità o cambiamento di commerciante, rigenera i tuoi profili di provisioning e reinstalla l'applicazione su un dispositivo reale.
Expo — dichiarare il diritto di app.json e di eseguire npx expo prebuild per applicarlo:
{
"expo": {
"ios": {
"entitlements": {
"com.apple.developer.in-app-payments": ["merchant.io.your-domain.com"]
}
}
}
}Reazione CLI— aggiungerlo ios/<AppName>/<AppName>.entitlements:
<key>com.apple.developer.in-app-payments</key>
<array>
<string>merchant.io.your-domain.com</string>
</array>import { useState, useEffect } from 'react';
import { DeunaSDK } from '@deuna/react-native-sdk';
// 1) Initialize the SDK
const sdk = new DeunaSDK({
publicApiKey: '<YOUR_PUBLIC_API_KEY>',
environment: 'sandbox', // 'production' | 'sandbox'
});
// 2) Check availability
const available = await sdk.getWalletsAvailable();
// 3) Launch
if (available.includes('apple_pay')) {
sdk.initElements({
orderToken: '<order-token>', // required
types: [{ name: 'apple_pay' }],
userInfo: { // required
email: '<email>',
firstName: '<firstName>',
lastName: '<lastName>',
},
callbacks: {
onSuccess: (payload) => {
const cardId = payload?.card_id;
// use cardId to process payment on your backend
},
onError: (error) => {
console.error('Payment failed:', error.metadata.message);
},
onClosed: (action) => {
console.log('Sheet dismissed by', action);
},
},
});
}4. Gotchas#
| Presa | Fisso |
|---|---|
| Pulsante non rende | Check getWalletsAvailable() risultato, supporto del browser e HTTPS. |
| Il foglio di pagamento si apre poi congela | La convalida del Merchant non è riuscita — controlla il file di verifica del dominio e le credenziali DEUNA. |
session.begin() silenziosamente respinta | Hai perso il gesto dell'utente. Non lo so. await lavoro di lunga durata tra clic e session.begin(). Usare orderToken + userInfo SSR percorso per pre-risolvere transactionInfo. |
| Funziona in Safari, non Chrome | Attesi — il foglio nativo richiede Safari. Altri browser ritornano al flusso QR-code (iOS 18+). |
Breve riferimento
| API | Oggetto |
|---|---|
DeunaSDK.getWalletsAvailable() | Controllare quali portafogli sono disponibili sul dispositivo. |
DeunaSDK.initElements({ types, orderToken?, callbacks }) | Inizializzare Apple Pay. Ritieni il tuo pulsante Apple Pay |
DeunaSDK.initPaymentWidget({ orderToken, callbacks, ... }) | Aprire il Widget di pagamento completo della DEUNA (Apple Pay incluso). |
.well-known/apple-developer-merchantid-domain-association | File di verifica del dominio che devi ospitare su ogni dominio |