Elabora il tuo primo pagamento sandbox
Elaborare un pagamento di ordine sandbox dal tuo backend mercantile e confermare il risultato finale attraverso un webhook verificato.
In questa pagina
Questo Quickstart utilizza il punto finale di acquisto di back-end del commerciante. Prima di iniziare, completa Impostazione account, scegli la tua integrazione, e confermare che il vostro commerciante di sandbox ha:
- Una chiave API privata memorizzata sul server.
- Almeno una connessione di pagamento attiva e una strategia di routing.
- Un token di ordine e un gettone di pagamento-metodo creato dalla vostra integrazione client selezionata.
- Un endpoint HTTPS pubblico che può ricevere i webhooks DEUNA.
Preparare la richiesta del server#
Caricare la chiave privata sandbox dalla memoria segreta del server. Tenere il token di ordine e il gettone di pagamento-metodo prodotto dallo stesso flusso di sandbox disponibile per l'organismo di richiesta.
DEUNA_PRIVATE_API_KEY=YOUR_SANDBOX_PRIVATE_API_KEYElaborare il pagamento dell'ordine#
Invia l'ordine e il metodo di pagamento tokenized al punto finale di acquisto verificato commerciante. Riutilizzare lo stesso X-Idempotency-Key e richiedere corpo se un timeout di rete rende il risultato incerto.
curl --request POST \
--url https://api.sandbox.deuna.io/v2/merchants/orders/purchase \
--header "X-Api-Key: ${DEUNA_PRIVATE_API_KEY}" \
--header "X-Idempotency-Key: order_1042-attempt_1" \
--header "Content-Type: application/json" \
--data '{
"order_token": "YOUR_SANDBOX_ORDER_TOKEN",
"payer_info": {
"email": "buyer@example.com",
"external_user_id": "customer_1042"
},
"payment_source": {
"method_type": "credit_card",
"payment_method": "YOUR_PAYMENT_METHOD_TOKEN"
}
}'const response = await fetch("https://api.sandbox.deuna.io/v2/merchants/orders/purchase", {
method: "POST",
headers: {
"X-Api-Key": "${DEUNA_PRIVATE_API_KEY}",
"X-Idempotency-Key": "order_1042-attempt_1",
"Content-Type": "application/json"
},
body: JSON.stringify({
"order_token": "YOUR_SANDBOX_ORDER_TOKEN",
"payer_info": {
"email": "buyer@example.com",
"external_user_id": "customer_1042"
},
"payment_source": {
"method_type": "credit_card",
"payment_method": "YOUR_PAYMENT_METHOD_TOKEN"
}
})
});
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
const data = await response.json();import requests
response = requests.request(
"POST",
"https://api.sandbox.deuna.io/v2/merchants/orders/purchase",
headers={
"X-Api-Key": "${DEUNA_PRIVATE_API_KEY}",
"X-Idempotency-Key": "order_1042-attempt_1",
"Content-Type": "application/json"
},
json={
"order_token": "YOUR_SANDBOX_ORDER_TOKEN",
"payer_info": {
"email": "buyer@example.com",
"external_user_id": "customer_1042"
},
"payment_source": {
"method_type": "credit_card",
"payment_method": "YOUR_PAYMENT_METHOD_TOKEN"
}
},
)
response.raise_for_status()
data = response.json()<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sandbox.deuna.io/v2/merchants/orders/purchase",
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"X-Api-Key: ${DEUNA_PRIVATE_API_KEY}",
"X-Idempotency-Key: order_1042-attempt_1",
"Content-Type: application/json"
],
CURLOPT_POSTFIELDS => json_encode([
"order_token" => "YOUR_SANDBOX_ORDER_TOKEN",
"payer_info" => [
"email" => "buyer@example.com",
"external_user_id" => "customer_1042"
],
"payment_source" => [
"method_type" => "credit_card",
"payment_method" => "YOUR_PAYMENT_METHOD_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("https://api.sandbox.deuna.io/v2/merchants/orders/purchase"))
.header("X-Api-Key", "${DEUNA_PRIVATE_API_KEY}")
.header("X-Idempotency-Key", "order_1042-attempt_1")
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("{\n \"order_token\": \"YOUR_SANDBOX_ORDER_TOKEN\",\n \"payer_info\": {\n \"email\": \"buyer@example.com\",\n \"external_user_id\": \"customer_1042\"\n },\n \"payment_source\": {\n \"method_type\": \"credit_card\",\n \"payment_method\": \"YOUR_PAYMENT_METHOD_TOKEN\"\n }\n }"))
.build();
HttpResponse<String> response = HttpClient.newHttpClient().send(
request, HttpResponse.BodyHandlers.ofString()
);
System.out.println(response.body());
}
}package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
request, err := http.NewRequest("POST", "https://api.sandbox.deuna.io/v2/merchants/orders/purchase", strings.NewReader("{\n \"order_token\": \"YOUR_SANDBOX_ORDER_TOKEN\",\n \"payer_info\": {\n \"email\": \"buyer@example.com\",\n \"external_user_id\": \"customer_1042\"\n },\n \"payment_source\": {\n \"method_type\": \"credit_card\",\n \"payment_method\": \"YOUR_PAYMENT_METHOD_TOKEN\"\n }\n }"))
if err != nil { panic(err) }
request.Header.Set("X-Api-Key", "${DEUNA_PRIVATE_API_KEY}")
request.Header.Set("X-Idempotency-Key", "order_1042-attempt_1")
request.Header.Set("Content-Type", "application/json")
response, err := http.DefaultClient.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, _ := io.ReadAll(response.Body)
fmt.Println(string(body))
}L'esatto payment_source e qualsiasi specific_fields dipende dal metodo di pagamento selezionato e dal fornitore. Vedi Elaborare il pagamento di un ordine per il contratto di richiesta completo.
Maneggiare il risultato immediato#
Leggi order.payment.data.status e qualsiasi azione successiva richiesta dall'ordine restituito. Un HTTP 2xx significa DEUNA ha accettato o elaborato la richiesta; non prova di per sé che i soldi si sono mossi.
- Continuare la realizzazione solo per lo stato di successo confermato documentato in Flusso e stati di pagamento.
- Presentare qualsiasi azione del cliente, come l'autenticazione 3DS, prima di riprovare.
- Per risultati in sospeso o incerti, recuperare l'ordine originale invece di creare un tentativo duplicato.
- Utilizzare una nuova chiave di idempotency solo per un tentativo di pagamento materialmente nuovo.
Confermare lo stato finale#
Utilizzare la risposta sincrona per aggiornare l'esperienza del cliente, ma prendere decisioni di adempimento da ultimo stato verificato. Configurare un webhook mercantile, verificare la sua firma, deduplicare l'evento, e poi riconciliare l'ordine.
app.post('/webhooks/deuna', express.raw({type: 'application/json'}), async (request, response) => {
const event = verifyDeunaSignature(request.body, request.headers);
await storeEventOnce(event.id);
await reconcileOrder(event.data.order_token);
response.sendStatus(200);
});