Apple Pay via Widget
このページで
このガイドでは、 Apple Pay の統合について説明します DEUNA SDK の使用
| 決済ウィジェット | 支払いVault | |
|---|---|---|
| 機能概要** | 完全なチェックアウト処理: UI、決済処理、および確認 | カードのトークン化のみ - カード ID を返却 |
| 決済処理を行う主体 | DEUNA (内部) | あなた (バックエンドからの Purchase API を使用) |
| Apple Pay ボタン | DEUNA の iframe 内でレンダリング | あなた自身の UI 内でレンダリング |
| SDK メソッド | initPaymentWidget | initElements({ types: ['APPLE_PAY'] }) |
| 使用する状況 | スムーズな決済体験をご希望 | 決済フローを制御する必要がある場合、またはカード情報を後で使用する場合 |
1. 前提条件#
開始する前に、以下の条件を満たしていることを確認してください:
| 要件 | 備考 |
|---|---|
| DEUNA アカウント | DEUNA ダッシュボードで有効な商用アカウント。 |
publicApiKey | DEUNA から発行された公開 API キー。以下のために必要です。 DeunaSDK.initialize. |
orderToken | DEUNA Orders API を使用してバックエンドで生成。決済を開始するために必要。 |
userToken (オプション) | DEUNAの既知のユーザーに対してカードをトークン化する場合にのみ必要です。 |
| HTTPS ドメイン | Apple Pay は HTTPS でのページ配信を必要とします。 localhost 開発環境でのみ許可されています。 |
| 互換性要件 | 公式の Web上のApple Pay および Apple Pay 実装 ドキュメントを参照してください。 Apple Pay は Safari (iOS 10 以降) または macOS 10.12 以降が必要です。 Chrome、Edge、Firefox などの Safari 以外のブラウザでは、iOS 18 以降の iPhone を使用しているユーザー向けに QR コードフローが利用可能です。 |
1.1. ドメイン認証 (両方のパスで必要)
Apple Pay ボタンを表示するすべてのドメイン(Payment Widget または Vault を使用する場合)は、DEUNA を通じて Apple に登録する必要があります。これは、本番環境だけでなく、開発またはプレビュー環境にも適用されます。
手順
- ドメイン関連ファイルを取得 DEUNA ダッシュボード(または、独自の商用 ID を使用している場合は Apple Pay から)から。ファイル名は通常、
apple-developer-merchantid-domain-association(拡張子なし) または.txt. - ファイルの内容をそのままホストしてください。 以下の場所にホストしてください:
以下の点を確認してください:Plain text
https://<your-domain>/.well-known/apple-developer-merchantid-domain-association- レスポンスは、 HTTPS.
Content-Type経由で提供されます。text/plain; charset=utf-8.- リダイレクト、認証不要、404エラーは発生しません。レスポンスは以下の内容である必要があります。
200 OK.
- ドメインの検証 は、DEUNAダッシュボード(またはApple Pay開発者ポータル)で行ってください。Appleは、サーバーからファイルを取得します。ファイルが一致する場合、ドメインは登録されます。
- 各ドメインに対して繰り返してください。 どのホスト名がウィジェットを読み込む場合(例:
checkout.mystore.com,staging.mystore.com)、そのホスト名はファイルを提供し、個別に登録する必要があります。
Next.js - 例
このリポジトリには、すでに検証エンドポイントが実装されています。 以下の2つの機能が設定されています:
next.config.js — 既定のパスと .txt パスを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 — ファイルの内容を 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);
}ファイルの内容は、環境変数 (NEXT_PUBLIC_APPLE_VALIDATION_CONTENT_FILE) したがって、環境ごとに変更できるよう、コードの変更なしでローテーションできます。
動作確認方法
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))
}期待される:
- HTTP
200 OK Content-Type: text/plain; charset=utf-8- 本文は、
7B22...(Apple の API)
2. リリース 統合#
ご使用の特定の統合に応じて、DEUNAのSDKに関する「開始」ガイドを参照してください。
2.1. 決済ウィジェット
Apple Pay に関する特記事項
- 追加の設定は不要です。Apple PayはDEUNAダッシュボードで有効または無効になります。商社が有効にし、デバイスが対応している場合、ボタンは自動的に表示されます。
userTokenオプション – 既存のDEUNAユーザーアカウントとの連携が必要な場合にのみ必要。- 標準ウィジェットのコールバック (
onSuccess,onError,onClosed,onPaymentProcessing) は、他の決済方法と同様に動作します。
決済ウィジェットで getWalletsAvailable をいつ呼び出す必要がありますか?
すべての決済方法を有効にした状態でウィジェットを開くと、このメソッドを呼び出す必要はありません。DEUNAは決済方法セレクター(ウォレットボタンを含む)をレンダリングし、利用可能性を内部で解決します。
以下の状況で必要です: getWalletsAvailable ウィジェット内でApple Payボタンを自分でレンダリングし、決済ウィジェットをスタンドアロンモードで使用して、直接その決済方法に移行する場合。その場合、事前に呼び出して、ボタンを表示するかどうかを決定してください。
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. 決済保管
Web SDK
Web SDK を使用して、DEUNA のバックエンドから Apple Pay の認証情報を取得します。 publicApiKey および(オプションで) orderToken.
詳細については、こちらを参照してください。 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.');
}iOS SDK
Apple Pay ウォレットの要件 (iOS)
iOS での SDK を使用して Apple Pay ウォレットを使用するには、以下のすべての設定が正しく構成されていることを確認してください。
-
アプリとチームの設定
- あなたのアプリケーションは、 Apple Developer Team が持っている Apple Payに対応.
- 対象 PRODUCT_BUNDLE_IDENTIFIER 必須要件 App ID Apple Developerで設定する必要があります。
- アプリは 実のiOSデバイスにインストールする必要があります。 (Apple Payはシミュレーターでは完全に動作しません)。
-
商取引IDの設定
- Apple Developerで商取引IDを作成するか、既存のものを利用してください(例:merchant.test.deuna.dev.pay)。
- 作成した商取引IDを、Identifiers > App ID > Apple Pay のアプリIDに割り当てます。
- Xcodeで、Signing & Capabilities > Apple Pay を有効にし、同じ商取引IDを選択します。
-
必要な証明書
SDKで使用する商取引IDに対して、以下の証明書が必要です。- Apple Pay 決済処理証明書 (アプリ内でのApple Payトークン処理に必要な証明書)。
-
プロビジョニングプロファイル
- Apple Payの機能や商取引IDの割り当てを変更した場合は、プロビジョニングプロファイルを再生成してください。
- プロファイル/機能変更後は、アプリを再インストールしてください(Clean Build Folder + デバイスからアプリを削除 + 再インストール)。
-
SDK/バックエンドの一貫性要件
-
バックエンドの認証情報(external_merchant_id)で返される商取引IDは、アプリのエンタイトルメントで有効になっている商取引IDと完全に一致する必要があります。
-
SDKのウォレットフローで、バックエンドが必要に応じてユーザーコンテキスト(userInfo)を渡す必要があります。これにより、ユーザートークンとユーザーIDを返すことができます。
-
ユーザートークン/ユーザーIDが不足している場合、Apple PayのUIが開いたとしても、トークン化が失敗する可能性があります。
-
ステップ1 — 準備状況の確認 決済ステップの前に、getWalletsAvailable()を一度呼び出します。SDKは、DEUNAの商取引設定と、デバイス上のApple Payの利用可能性を検証します。
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() 結果をキャッシュします。その後の呼び出しは、キャッシュされたウォレットを即座に返します。そのため、各画面のロード時に呼び出すことが安全です。
ステップ2 — Apple Payの起動 ユーザーがApple Payボタンをタップしたときに、initElementsをAPPLE_PAYとして呼び出します。SDKは注文の認証情報を取得し、ネイティブのApple Payシートを起動します。
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
)React Native SDK
WebViewを使用せずに、ネイティブのApple Payシートを直接表示したい場合に、このパスを使用します。SDKはデバイスの可用性を確認し、DEUNAのバックエンドからApple Payの認証情報を取得し、支払いシートを起動します。結果として、トークン化されたカードのペイロードが、onSuccessコールバックに送信されます。
前提条件:
- アプリのターゲットでApple Pay機能を有効にします(Xcode → ターゲット → Signing & Capabilities → + Capability → Apple Pay)。
- その機能に、Merchant IDを追加します(例:merchant.io.your-domain.com)。
- 同じMerchant IDは、DEUNAの認証情報(external_merchant_id)で返される必要があります。DEUNAのチームに確認してください。
- 「 Apple Developer Portal、そのMerchant IDには、有効なApple Pay Payment Processing Certificateが必要です。
- 機能またはMerchant IDの変更後、プロビジョニングプロファイルを再生成し、実際のデバイスにアプリを再インストールしてください。
Expo — app.jsonで entitlementを宣言し、npx expo prebuildを実行して適用します:
{
"expo": {
"ios": {
"entitlements": {
"com.apple.developer.in-app-payments": ["merchant.io.your-domain.com"]
}
}
}
}React Native CLI— を追加 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. 注意事項#
| 注意 | 修正 |
|---|---|
| ボタンが表示されない | 確認 getWalletsAvailable() 結果、ブラウザのサポート、およびHTTPS。 |
| 支払いシートが開いた後、フリーズする | 商人の検証に失敗しました—ドメインの検証ファイルとDEUNAの認証情報を確認してください。 |
session.begin() 無効な認証 | ユーザーの操作を失いました。 await 長期間にわたる処理を、クリックから開始する。 session.begin()以下の orderToken + userInfo SSRパスを使用して、事前に解決する。 transactionInfo. |
| Safariで動作し、Chromeでは動作しない。 | 期待される動作:ネイティブのシートはSafariを必要とする。他のブラウザはQRコードフロー(iOS 18以降)にフォールバックする。 |
クイックリファレンス
| API | 目的 |
|---|---|
DeunaSDK.getWalletsAvailable() | デバイスで利用可能なウォレットを確認する。 |
DeunaSDK.initElements({ types, orderToken?, callbacks }) | Apple Payを初期化する。独自のApple Payボタンをレンダリングする。 |
DeunaSDK.initPaymentWidget({ orderToken, callbacks, ... }) | DEUNAのフルペイメントウィジェット(Apple Payを含む)を開く。 |
.well-known/apple-developer-merchantid-domain-association | ドメイン検証ファイルは、すべてのドメインでホストする必要がある。 |