Processe seu primeiro pagamento sandbox
Processe o pagamento de um pedido sandbox do back-end do seu comerciante e confirme o resultado final por meio de um webhook verificado.
Nesta página
Este guia de início rápido usa o endpoint de compra de back-end do comerciante. Antes de começar, complete configuração da conta, escolha sua integraçãoe confirme se seu comerciante sandbox tem:
- Uma chave de API privada armazenada em seu servidor.
- Pelo menos uma conexão de pagamento ativa e uma estratégia de roteamento.
- Um token de pedido e um token de método de pagamento criados pela integração do cliente selecionado.
- Um endpoint HTTPS público que pode receber webhooks DEUNA.
Preparar a solicitação do servidor#
Carregue a chave privada da sandbox do armazenamento secreto do seu servidor. Mantenha o token do pedido e o token do método de pagamento produzidos pelo mesmo fluxo de sandbox disponíveis para o corpo da solicitação.
DEUNA_PRIVATE_API_KEY=YOUR_SANDBOX_PRIVATE_API_KEYProcessar o pagamento do pedido#
Envie o pedido e a forma de pagamento tokenizada para o endpoint de compra do comerciante verificado. Reutilize o mesmo X-Idempotency-Key e solicite o corpo se o tempo limite da rede tornar o resultado 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))
}O exato payment_source e qualquer specific_fields depende do método de pagamento e provedor selecionado. Veja Processar o pagamento do pedido para o contrato de solicitação completo.
Lidar com o resultado imediato#
Leia order.payment.data.status e qualquer próxima ação necessária do pedido devolvido. Um HTTP 2xx significa que a DEUNA aceitou ou processou o pedido; isso não prova por si só que o dinheiro foi movimentado.
- Continue o cumprimento apenas para o estado de sucesso confirmado documentado em Fluxo e status de pagamento.
- Apresente qualquer ação do cliente, como autenticação 3DS, antes de tentar novamente.
- Para resultados pendentes ou incertos, recupere o pedido original em vez de criar uma tentativa duplicada.
- Use uma nova chave de idempotência apenas para uma tentativa de pagamento materialmente nova.
Confirme o estado final#
Use a resposta síncrona para atualizar a experiência do cliente, mas tome decisões de atendimento a partir do estado verificado mais recente. Configure um webhook do comerciante, verifique sua assinatura, desduplique o evento e reconcilie o pedido.
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);
});