PayPal Direct API経由
このページには、DEUNA APIを使用してPayPalを統合するための手順が含まれています。
次の項目を取得したら、 order_tokenを取得したら、以下の手順を実行する必要があります。
1. ユーザーの作成
DEUNAでユーザーを作成し、後で購入を実行するための認証トークンを取得します。このAPIは、ユーザーの token これらが次の手順を実行するために必要となります。
ユーザーを作成するには、以下の手順に従ってください。 Referencia de APIすでに使用されているメールアドレスの場合、APIは以下のメッセージを返します。 user already existsその後、OTPをリクエストし、 OTPを使用してログインし、新しいユーザーを取得して購入手続きを進めます。 OTPを取得 OTPを使用してログイン 新しいユーザーを取得 token 購入手続きを進める。
2. 支払い方法の取得
PayPal Walletの設定を取得するために、支払い方法を確認する必要があります。以下の手順に従ってください。 ガイド.
-
リクエストペイロード
curl --location '{{base_url}}/merchants/orders/{{order_token}}/payments-methods' \ --header 'x-api-key: {{merchant_private_key}}' \ --header 'Authorization: Bearer {{user_token}}'const response = await fetch("{{base_url}}/merchants/orders/{{order_token}}/payments-methods", { method: "GET", headers: { "x-api-key": "{{merchant_private_key}}", "Authorization": "Bearer {{user_token}}" } }); if (!response.ok) throw new Error(`Request failed: ${response.status}`); const data = await response.json();import requests response = requests.request( "GET", "{{base_url}}/merchants/orders/{{order_token}}/payments-methods", headers={ "x-api-key": "{{merchant_private_key}}", "Authorization": "Bearer {{user_token}}" }, ) response.raise_for_status() data = response.json()<?php $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "{{base_url}}/merchants/orders/{{order_token}}/payments-methods", CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "x-api-key: {{merchant_private_key}}", "Authorization: Bearer {{user_token}}" ] ]); $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("{{base_url}}/merchants/orders/{{order_token}}/payments-methods")) .header("x-api-key", "{{merchant_private_key}}") .header("Authorization", "Bearer {{user_token}}") .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", "{{base_url}}/merchants/orders/{{order_token}}/payments-methods", nil) if err != nil { panic(err) } request.Header.Set("x-api-key", "{{merchant_private_key}}") request.Header.Set("Authorization", "Bearer {{user_token}}") response, err := http.DefaultClient.Do(request) if err != nil { panic(err) } defer response.Body.Close() body, _ := io.ReadAll(response.Body) fmt.Println(string(body)) } -
応答
JSON{ "data": [ { "enabled": true, "method_type": "wallet", "processor_name": "paypal_wallet", // PayPal Wallet identifier "exclude_cvv": false, "stored_payment_methods": [ { "payment_method": "adb1ef51-e073-49f5-ba3b-a7e42344fd15", "account_identifier": "johndoe@deuna.com" } ], "id": "58745b8e-7127-44ea-84ef-656b3ffc611b", // Payment method ID "authorization": { "required": true, // true | false "flow": "consent" } } ] }
購入フロー#
取得した支払い方法の情報に基づいて、以下の手順で購入を完了できます。
Vaulting (保存) を使用しない場合
この手順は、PayPalアカウントのトークン化が不要な場合に適用されます。
取得した 支払い方法の取得 以下のような流れで操作を行います。
{
"data": [
{
"enabled": true,
"method_type": "wallet",
"processor_name": "paypal_wallet", // PayPal Wallet identifier
"exclude_cvv": false,
"stored_payment_methods": [],
"id": "58745b8e-7127-44ea-84ef-656b3ffc611b", // Payment method ID
"authorization": {
"required": false,
"flow": "consent"
}
}
]
}このフローでは、以下の手順を実行する必要があります。
-
購入を実行する
-
以下の Purchase V2 ガイド以下は、PayPal Walletでの購入に必要なフィールドのリストです。
フィールド 説明 Value order.callback_urls.on_success購入をPayPalウォレットアカウントで承認した後にリダイレクトされるURL。 https://example.com/payment_source.method_typeDEUNAの支払い方法の種類。 walletpayment_source.processorPayPalウォレットの支払い方法識別子。 paypal_walletリクエストペイロード
JSON{ "order_type": "DEUNA_CHECKOUT", "order_token": "{{order-token}}", "order": { "callback_urls": { "on_success": "https://example.com" // required for PayPal Wallet } }, "payer_info": { "email": "johndoe@deuna.com" }, "payment_source": { "method_type": "wallet", // required for PayPal Wallet "processor": "paypal_wallet" // required for PayPal Wallet }, "anti_fraud_info": { "device": { "id": "xxxxxxx" // PayPal device ID, used in STC } } }
応答
JSON{ "order": { "order_id": "620bbbf4-1f08-4cda-8609-dade541cb80e", "store_code": "all", "currency": "MXN", "tax_amount": 0, "display_tax_amount": "", "shipping_amount": 0, "display_shipping_amount": "MXN 0.00", "items_total_amount": 2175, "display_items_total_amount": "MXN 21.75", "sub_total": 2075, "display_sub_total": "MXN 20.75", "total_amount": 2190, "display_total_amount": "MXN 21.90", "items": [ { "id": "849fd015-2e1b-4ccc-a00c-aacbefeb71c8", "name": "Papas", "description": "Papas fritas con paprica", "options": "", "total_amount": { "amount": 2100, "original_amount": 2100, "display_amount": "MXN 21.00", "display_original_amount": "MXN 21.00", "currency": "MXN", "currency_symbol": "$", "total_discount": 100, "display_total_discount": "MXN 1.00" }, "unit_price": { "amount": 1050, "display_amount": "MXN 10.50", "currency": "MXN", "currency_symbol": "$" }, "tax_amount": { "amount": 50, "display_amount": "MXN 0.50", "currency": "MXN", "currency_symbol": "$" }, "quantity": 2, "uom": "", "upc": "", "sku": "", "isbn": "", "brand": "", "manufacturer": "", "category": "", "color": "", "size": "", "weight": { "weight": 0, "unit": "" }, "image_url": "https://media-cdn.tripadvisor.com/media/photo-s/1a/e2/c6/68/porcion-de-papas-a-la.jpg", "details_url": "", "type": "", "taxable": true, "discounts": [], "included_in_subscription": false, "item_details": [] }, { "id": "c871341d-317b-4fdb-9d72-b55e55958633", "name": "Refresco", "description": "Coca-cola Sprite", "options": "", "total_amount": { "amount": 90, "original_amount": 75, "display_amount": "MXN 0.90", "display_original_amount": "MXN 0.75", "currency": "MXN", "currency_symbol": "$", "total_discount": 0, "display_total_discount": "MXN 0.00" }, "unit_price": { "amount": 75, "display_amount": "MXN 0.75", "currency": "MXN", "currency_symbol": "$" }, "tax_amount": { "amount": 15, "display_amount": "MXN 0.15", "currency": "MXN", "currency_symbol": "$" }, "quantity": 1, "uom": "", "upc": "", "sku": "", "isbn": "", "brand": "", "manufacturer": "", "category": "", "color": "", "size": "", "weight": { "weight": 0, "unit": "" }, "image_url": "https://media-cdn.tripadvisor.com/media/photo-s/1a/e2/c6/68/porcion-de-papas-a-la.jpg", "details_url": "", "type": "", "taxable": true, "discounts": [], "included_in_subscription": false, "item_details": [] } ], "discounts": [], "shipping_address": { "id": 762, "user_id": "", "first_name": "Pablo", "last_name": "Murillo", "phone": "+551146733466", "identity_document": "", "lat": -22.943934, "lng": -43.182984, "address1": "Jose luis lagrange 3, 12", "address2": "Polanco I Sección", "city": "MIGUEL HIDALGO", "zipcode": "11510", "state_name": "CIUDAD DE MÉXICO", "country_code": "MX", "additional_description": "confirmar", "address_type": "home", "is_default": false, "created_at": "2025-02-26T21:38:07Z", "updated_at": "2025-02-26T21:38:07Z", "identity_document_type": "", "email": "johndoe@deuna.com", "state_code": "", "country": "MX" }, "shipping_options": null, "user_instructions": "", "metadata": { "cd_string_one": 1, "highrisk_txn_flag": 1, "vertical": "Retail" }, "status": "pending", "payment": { "data": { "amount": { "amount": 2190, "currency": "MXN" }, "metadata": { "authorization_code": "", "external_transaction_id": "6L9248503S6803027" }, "from_card": { "card_brand": "", "first_six": "", "last_four": "", "bank_name": "", "country_iso": "", "credential_source": "", "expiry_month": "", "expiry_year": "" }, "updated_at": "2025-02-26 21:38:12.748800962 +0000 UTC", "method_type": "wallet", "merchant": { "store_code": "all", "id": "2a18bdc9-d617-45cc-b718-838451dcf33a", "affiliation_code": "", "mcc": "" }, "created_at": "2025-02-26 21:38:12.747998969 +0000 UTC", "id": "620bbbf4-1f08-4cda-8609-dade541cb80e", "processor": "paypal_wallet", "customer": { "email": "user_dev_219@testuser.com", "id": "9d920735-c3b1-4908-aba2-762d86fda7e0", "first_name": "", "last_name": "" }, "status": "pending", "reason": "", "external_transaction_id": "6L9248503S6803027", "merchant_payment_processor_name": "", "authorization_code": "", "installment_interest_calculations": null, "next_action": { "action": "authorization_wallet", "url": "", "authorization_wallet": { "token": "6L9248503S6803027", "redirect_url": "https://www.sandbox.paypal.com/checkoutnow?token=6L9248503S6803027" } }, "merchant_payment_processor_id": "" } }, "gift_card": [], "redirect_url": "", "webhook_urls": null, "total_discount": 0, "display_total_discount": "MXN 0.00", "shipping": null, "cash_change": 0, "shipping_method": null, "shipping_methods": [], "timezone": "", "scheduled_at": "", "billing_address": { "id": 191, "user_id": "", "first_name": "Pablo", "last_name": "Murillo", "phone": "+551146733466", "identity_document": "", "lat": -22.943934, "lng": -43.182984, "address1": "Jose luis lagrange 3, 12", "address2": "Polanco I Sección", "city": "MIGUEL HIDALGO", "zipcode": "11510", "state_name": "CIUDAD DE MÉXICO", "country_code": "MX", "additional_description": "confirmar", "address_type": "home", "is_default": false, "created_at": "2025-02-26T21:38:07Z", "updated_at": "2025-02-26T21:38:07Z", "email": "johndoe@deuna.com", "identity_document_type": "", "country": "" }, "payment_link": "", "display_shipping_tax_amount": "MXN 0.00", "display_total_tax_amount": "MXN 1.15", "shipping_tax_amount": 0, "total_tax_amount": 115, "user_id": "", "include_payment_options": [], "redirect_urls": { "success": "", "pending": "", "error": "", "fallback": "", "close": "" }, "created_at": "", "updated_at": "", "payer_info": null, "discount_amount": 100, "shipping_discount_amount": 0, "device_fingerprint": "", "expired_at": "", "version": "0", "fraud": { "analysis": { "score": 0.113950945, "processor": "SIFT", "risk_level": "", "status": "automatic_decision", "type": "", "fraud_decision": "", "details": "", "processor_response": "" } }, "display_total_interest_amount": "", "payment_method": "", "token": "", "statement_descriptor": "", "browser_details": { "screen_height": 1000, "screen_width": 2000, "user_agent": "", "ip_address": "", "color_depth": 0, "java_enabled": false, "java_script_enabled": false, "language": "", "time_zone_offset": 0, "accept_header": "" }, "callback_urls": null }, "custom_fields": [] } -
-
PayPal へのリダイレクト
購入 API は、以下を含むレスポンスを返します
pendingステータスとnext_actionを含む、ユーザーをリダイレクトする PayPal チェックアウト URL。JSON{ "order": { "order_id": "620bbbf4-1f08-4cda-8609-dade541cb80e", "store_code": "all", "currency": "MXN", "tax_amount": 0, "display_tax_amount": "", "shipping_amount": 0, "display_shipping_amount": "MXN 0.00", "items_total_amount": 2175, "display_items_total_amount": "MXN 21.75", "sub_total": 2075, "display_sub_total": "MXN 20.75", "total_amount": 2190, "display_total_amount": "MXN 21.90", ... "status": "pending", "payment": { "data": { "method_type": "wallet", "processor": "paypal_wallet", "status": "pending", "external_transaction_id": "6L9248503S6803027", "next_action": { "action": "authorization_wallet", "url": "", "authorization_wallet": { "token": "6L9248503S6803027", "redirect_url": "https://www.sandbox.paypal.com/checkoutnow?token=6L9248503S6803027" } }, ... } }, "created_at": "", "updated_at": "", ... }, "custom_fields": [] } -
注文の状態を確認する(ポーリング)。
PayPal へのリダイレクト後、ユーザーがアカウントを使用して支払いを確認する間、ステータスの変更をポーリングする必要があります。
以下の手順を実行する必要があります。 Get Order および、以下のステータスを確認する必要があります。
payment.data.status.期待されるステータスは以下のとおりです。
pending: ユーザーが PayPal でまだ支払いを確認していません。processed: ユーザーが PayPal で支払いを確認し、決済が成功しました。denied: 決済処理中にエラーが発生しました。
応答
JSON{ "token": "ce7f91cc-7306-4a36-b9a8-b266545c56ba", "order_type": "DEUNA_CHECKOUT", "order": { "order_id": "620bbbf4-1f08-4cda-8609-dade541cb80e", "store_code": "all", "currency": "MXN", "tax_amount": 0, "display_tax_amount": "MXN 0.00", "shipping_amount": 0, "display_shipping_amount": "MXN 0.00", "items_total_amount": 2175, "display_items_total_amount": "MXN 21.75", "sub_total": 2075, "display_sub_total": "MXN 20.75", "total_amount": 2190, "display_total_amount": "MXN 21.90", "discounts": [], "status": "succeeded", "payment": { "data": { "method_type": "wallet", "processor": "paypal_wallet", "status": "processed", "external_transaction_id": "5S773340XV029382D" } }, "created_at": "2025-02-26 21:38:07.860816361 +0000 UTC", "updated_at": "", "callback_urls": null }, "custom_fields": [], "checkout_modules": [], "refunds": [] }
Vaulting を使用する場合
これは、PayPal アカウントのトークン化が必要な場合に、購入を完了するための手順です。
取得した 支払い方法の取得 以下のような流れで操作を行います。
{
"data": [
{
"enabled": true,
"method_type": "wallet",
"processor_name": "paypal_wallet", // PayPal Wallet identifier
"exclude_cvv": false,
"stored_payment_methods": [
{
"payment_method": "adb1ef51-e073-49f5-ba3b-a7e42344fd15",
"account_identifier": "johndoe@deuna.com"
}
],
"id": "58745b8e-7127-44ea-84ef-656b3ffc611b", // Payment method ID
"authorization": {
"required": true,
"flow": "consent"
}
}
]
}この時点で、ユーザーは新しいアカウントを追加するか、以前にトークン化されたアカウントを使用して購入を完了するオプションが表示されます。
-
新しい PayPal アカウントを追加する
Para tokenizar una nueva cuenta, se deben seguir los siguientes pasos:
- Crear el consentimiento del cliente.
En este paso, crearemos una solicitud de autorización de PayPal para el usuario.- 要求
curl --location --request POST '{{base_url}}/merchants/orders/{{order_token}}/consent?payment_method_id={{payment_method_id}}' \ --header 'X-API-KEY: {{merchant_private_key}}' \ --header 'Content-Type: application/json' \ --header 'X-Request-Id: xxxxx' \ --header 'Authorization: Bearer {{user_token}}'const response = await fetch("{{base_url}}/merchants/orders/{{order_token}}/consent?payment_method_id={{payment_method_id}}", { method: "POST", headers: { "X-API-KEY": "{{merchant_private_key}}", "Content-Type": "application/json", "X-Request-Id": "xxxxx", "Authorization": "Bearer {{user_token}}" } }); if (!response.ok) throw new Error(`Request failed: ${response.status}`); const data = await response.json();import requests response = requests.request( "POST", "{{base_url}}/merchants/orders/{{order_token}}/consent?payment_method_id={{payment_method_id}}", headers={ "X-API-KEY": "{{merchant_private_key}}", "Content-Type": "application/json", "X-Request-Id": "xxxxx", "Authorization": "Bearer {{user_token}}" }, ) response.raise_for_status() data = response.json()<?php $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "{{base_url}}/merchants/orders/{{order_token}}/consent?payment_method_id={{payment_method_id}}", CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "X-API-KEY: {{merchant_private_key}}", "Content-Type: application/json", "X-Request-Id: xxxxx", "Authorization: Bearer {{user_token}}" ] ]); $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("{{base_url}}/merchants/orders/{{order_token}}/consent?payment_method_id={{payment_method_id}}")) .header("X-API-KEY", "{{merchant_private_key}}") .header("Content-Type", "application/json") .header("X-Request-Id", "xxxxx") .header("Authorization", "Bearer {{user_token}}") .method("POST", 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("POST", "{{base_url}}/merchants/orders/{{order_token}}/consent?payment_method_id={{payment_method_id}}", nil) if err != nil { panic(err) } request.Header.Set("X-API-KEY", "{{merchant_private_key}}") request.Header.Set("Content-Type", "application/json") request.Header.Set("X-Request-Id", "xxxxx") request.Header.Set("Authorization", "Bearer {{user_token}}") response, err := http.DefaultClient.Do(request) if err != nil { panic(err) } defer response.Body.Close() body, _ := io.ReadAll(response.Body) fmt.Println(string(body)) } - 応答
JSON
{ "id": "1625a32a-df4c-4d9b-aec1-4510b3625865", "type": "transaction.authentication.pending", "created": "1740608931", "data": { "order": { "order_token": "7e975d44-a061-4d70-af0f-673f6ee56445", "transaction_id": "51b38afd-150f-419a-b718-b583209160fe", "external_transaction_id": "" }, "consent": { "id": "6fe9a045-9a46-4b25-8b60-d5a9586494c5", "status": "pending", "expires_at": "2025-02-26T22:38:51Z", "authorization_id": "5KA20765HT8087515", "redirect_url": "https://www.sandbox.paypal.com/agreements/approve?approval_session_id=5KA20765HT8087515" }, "error": null } }
- 要求
- PayPal へのリダイレクト
La API devolverá el consentimiento comopendingy una URL de PayPal donde el usuario debe ingresar sus detalles de cuenta y autorizar su uso.JSON{ "id": "1625a32a-df4c-4d9b-aec1-4510b3625865", "type": "transaction.authentication.pending", "created": "1740608931", "data": { "order": { "order_token": "7e975d44-a061-4d70-af0f-673f6ee56445", "transaction_id": "51b38afd-150f-419a-b718-b583209160fe", "external_transaction_id": "" }, "consent": { "id": "6fe9a045-9a46-4b25-8b60-d5a9586494c5", "status": "pending", "expires_at": "2025-02-26T22:38:51Z", "authorization_id": "5KA20765HT8087515", "redirect_url": "https://www.sandbox.paypal.com/agreements/approve?approval_session_id=5KA20765HT8087515" }, "error": null } } - Obtener el estado de consentimiento del cliente (Polling)
Una vez que hayamos dirigido al usuario a PayPal, debemos verificar el estado del consentimiento mientras autoriza el uso de su cuenta, realizando un polling hasta que el estado cambie.- 要求
curl --location '{{base_url}}/merchants/orders/{{order_token}}/consent' \ --header 'X-API-KEY: {{merchant_private_key}}' \ --header 'Content-Type: application/json' \ --header 'X-Request-Id: xxxxx' \ --header 'Authorization: {{user_token}}'const response = await fetch("{{base_url}}/merchants/orders/{{order_token}}/consent", { method: "GET", headers: { "X-API-KEY": "{{merchant_private_key}}", "Content-Type": "application/json", "X-Request-Id": "xxxxx", "Authorization": "{{user_token}}" } }); if (!response.ok) throw new Error(`Request failed: ${response.status}`); const data = await response.json();import requests response = requests.request( "GET", "{{base_url}}/merchants/orders/{{order_token}}/consent", headers={ "X-API-KEY": "{{merchant_private_key}}", "Content-Type": "application/json", "X-Request-Id": "xxxxx", "Authorization": "{{user_token}}" }, ) response.raise_for_status() data = response.json()<?php $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "{{base_url}}/merchants/orders/{{order_token}}/consent", CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "X-API-KEY: {{merchant_private_key}}", "Content-Type: application/json", "X-Request-Id: xxxxx", "Authorization: {{user_token}}" ] ]); $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("{{base_url}}/merchants/orders/{{order_token}}/consent")) .header("X-API-KEY", "{{merchant_private_key}}") .header("Content-Type", "application/json") .header("X-Request-Id", "xxxxx") .header("Authorization", "{{user_token}}") .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", "{{base_url}}/merchants/orders/{{order_token}}/consent", nil) if err != nil { panic(err) } request.Header.Set("X-API-KEY", "{{merchant_private_key}}") request.Header.Set("Content-Type", "application/json") request.Header.Set("X-Request-Id", "xxxxx") request.Header.Set("Authorization", "{{user_token}}") response, err := http.DefaultClient.Do(request) if err != nil { panic(err) } defer response.Body.Close() body, _ := io.ReadAll(response.Body) fmt.Println(string(body)) } - 応答
期待されるステータスは以下のとおりです。JSON
{ "id": "4d226ecf-cd9a-4cc0-a3cf-fa8b2d0efab7", "type": "transaction.authentication.updated", "created": "1740609613", "callback_url": "", "data": { "request_id": "62551ffd-6d67-46cb-a436-f1ec3aa56087", "order": { "order_token": "00000000-0000-0000-0000-000000000000", "transaction_id": "", "external_transaction_id": "" }, "consent": { "id": "61fd7eb8-8a42-43fc-89d1-ab5c5ccaa0b9", "status": "success", "expires_at": "0001-01-01T00:00:00Z", "authorization_id": "95778196PH100683G", "redirect_url": "" }, "error": null } } pending: El usuario aún no ha autorizado el uso de su cuenta de PayPal.success: El usuario ha autorizado el uso de su cuenta de PayPal, y la cuenta se ha tokenizado correctamente.denied: Ha ocurrido un error al tokenizar la cuenta, o el usuario no ha autorizado el uso de su cuenta.expired: El usuario no ha autorizado el uso de su cuenta en el plazo.
Una vez que el consentimiento del usuario esté autorizado, la cuenta aparecerá en el
stored_payment_methodsde la respuesta de 支払い方法の取得.
JSON{ "data": [ { "enabled": true, "method_type": "wallet", "processor_name": "paypal_wallet", // PayPal Wallet identifier "exclude_cvv": false, "stored_payment_methods": [ { "payment_method": "6fe9a045-9a46-4b25-8b60-d5a9586494c5", // data.consent.id "account_identifier": "johndoe@deuna.com" } ], "id": "58745b8e-7127-44ea-84ef-656b3ffc611b", // Payment method ID "authorization": { "required": true, "flow": "consent" } } ] }En este punto, deberíamos tener una cuenta de PayPal tokenizada, estos tokens serán necesarios para los siguientes pasos. Esta cuenta token será el
payment_methodcampo de la lista destored_payment_methodsen la respuesta de 支払い方法の取得, o también puede ser eldata.consent.idcampo de la respuesta de API de 作成 または Obtener Consentimiento. - 要求
- Crear el consentimiento del cliente.
-
Planes de Pago (Opcional)
Podemos verificar los planes de pago disponibles para la cuenta de PayPal del usuario con la siguiente solicitud:
curl --location '{{base_url}}/merchants/transactions/orders/{{order_token}}/installments?payment_method={{payment_method}}&method_type=wallet&payment_method_id={{payment_method_id}}' \ --header 'x-api-key: {{merchant_public_key}}'const response = await fetch("{{base_url}}/merchants/transactions/orders/{{order_token}}/installments?payment_method={{payment_method}}&method_type=wallet&payment_method_id={{payment_method_id}}", { method: "GET", headers: { "x-api-key": "{{merchant_public_key}}" } }); if (!response.ok) throw new Error(`Request failed: ${response.status}`); const data = await response.json();import requests response = requests.request( "GET", "{{base_url}}/merchants/transactions/orders/{{order_token}}/installments?payment_method={{payment_method}}&method_type=wallet&payment_method_id={{payment_method_id}}", headers={ "x-api-key": "{{merchant_public_key}}" }, ) response.raise_for_status() data = response.json()<?php $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "{{base_url}}/merchants/transactions/orders/{{order_token}}/installments?payment_method={{payment_method}}&method_type=wallet&payment_method_id={{payment_method_id}}", CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "x-api-key: {{merchant_public_key}}" ] ]); $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("{{base_url}}/merchants/transactions/orders/{{order_token}}/installments?payment_method={{payment_method}}&method_type=wallet&payment_method_id={{payment_method_id}}")) .header("x-api-key", "{{merchant_public_key}}") .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", "{{base_url}}/merchants/transactions/orders/{{order_token}}/installments?payment_method={{payment_method}}&method_type=wallet&payment_method_id={{payment_method_id}}", nil) if err != nil { panic(err) } request.Header.Set("x-api-key", "{{merchant_public_key}}") response, err := http.DefaultClient.Do(request) if err != nil { panic(err) } defer response.Body.Close() body, _ := io.ReadAll(response.Body) fmt.Println(string(body)) }応答
JSON{ "installments": [ { "installments": 3, "installments_amount": 3333, "display_installments_amount": "MXN 33.33", "installment_rate": 0, "display_installment_label": "3 de $33.33 sin interés", "plan_option_id": "2e0cc595-40e6-4ecf-b43b-35d5c33f88b6", "installment_total_amount": 10000, "installment_tax": [], "display_installment_total_amount": "MXN 100.00" }, { "installments": 6, "installments_amount": 1666, "display_installments_amount": "MXN 16.66", "installment_rate": 0, "display_installment_label": "6 de $16.66 sin interés", "plan_option_id": "25c7ef41-ebe8-4197-bdb3-f8651c261ea8", "installment_total_amount": 10000, "installment_tax": [], "display_installment_total_amount": "MXN 100.00" } ] } -
購入を実行する
以下の Purchase V2 ガイド以下は、PayPal Walletでの購入に必要なフィールドのリストです。
フィールド 説明 Value payment_source.method_typeTipo de método de pago DEUNA walletpayment_source.processorPayPalウォレットの支払い方法識別子。 paypal_walletpayment_source.payment_methodToken de cuenta de PayPal. 6fe9a045-9a46-4b25-8b60-d5a9586494c5payment_source.payment_method_idEl ID de método de pago de PayPal Wallet se devuelve en el idcampo de la 支払い方法の取得 response.58745b8e-7127-44ea-84ef-656b3ffc611b- リクエストペイロード
JSON
{ "order_type": "DEUNA_CHECKOUT", "order_token": "{{order-token}}", "payer_info": { "email": "johndoe@deuna.com" }, "payment_source": { "method_type": "wallet", // required for PayPal Wallet "processor": "paypal_wallet", // required for PayPal Wallet "payment_method": "{{payment_method}}", // required "payment_method_id": "{{payment_method_id}}" // required }, "anti_fraud_info": { "device": { "id": "xxxxxxx" // PayPal device ID, used in STC } } }
応答
JSON{ "order_type": "DEUNA_CHECKOUT", "order_token": "c582917a-07d2-4f07-b107-fd535e5565cb", "order": { "order_id": "777e66e5-3326-4b04-ad0a-93be7f2028bb", "store_code": "all", "currency": "MXN", "tax_amount": 0, "display_tax_amount": "", "shipping_amount": 0, "display_shipping_amount": "MXN 0.00", "items_total_amount": 2175, "display_items_total_amount": "MXN 21.75", "sub_total": 2075, "display_sub_total": "MXN 20.75", "total_amount": 2190, "display_total_amount": "MXN 21.90", ... "status": "succeeded", "payment": { "data": { "method_type": "wallet", "processor": "paypal_wallet", "customer": { "email": "user_dev_219@testuser.com", "id": "9d920735-c3b1-4908-aba2-762d86fda7e0", "first_name": "", "last_name": "" }, "status": "processed", "external_transaction_id": "0YF74805EM9345944", ... } }, ... "callback_urls": null } }Estados Esperados:
succeeded: Pago completado con éxito.denied: 決済処理中にエラーが発生しました。
- リクエストペイロード
Integrar FraudNet#
Fraudnet es una biblioteca desarrollada por PayPal que analiza los datos enviados a través del navegador durante todo el proceso de compra para prevenir posibles fraudes en las transacciones.
Fraudnet debe estar en funcionamiento durante todo el proceso de transacción. Para su integración, PayPal proporciona la siguiente documentación: Integrar FraudNet
Montos de descuento#
Los descuentos en PayPal se pueden aplicar a nivel de pedido. En el payload, debe procesar cualquier descuento a través de discount_amount.