Skip to main content
On this page

Consent is the customer authorization that a supported wallet requires before DEUNA can retrieve payment options, store an account, or complete a purchase. DEUNA exposes one public consent contract while adapting the provider-specific flow behind it.

Supported providers and behavior#

ProviderWho uses consentApproval experienceStatus sourceReuse
NuPayGuest or authenticated customer, when enabled for the connectionThe customer approves in the Nubank experienceProvider webhook; GET /merchants/orders/{order_token}/consent returns the latest DEUNA stateBound to the order and customer identity; expired authorization can be refreshed when supported
PayPal WalletAuthenticated customer using PayPal VaultRedirect the customer to the returned redirect_urlDEUNA polls PayPal when the consent becomes eligible for verificationThe approved PayPal account is exposed as a stored payment method for later purchases

Other payment methods may use redirects, OTP, or 3DS, but they do not use this consent API. Do not call the consent endpoints unless the selected wallet connection is configured for consent.

Lifecycle#

Sequence diagram
1Merchant app2DEUNA3Wallet provider4Merchant webhookCreate orderPOST consentCreate authorizationpending + approval actionconsent.status = pendingPresent redirect or provider approvalGET consentlatest consent statusAuthorization updatetransaction.authentication.*Purchase with approved consent
Merchant or customerDEUNAProvider or processor

The normal state progression is pending to success. Treat failed and expired as terminal. Treat any unrecognized or denied state as non-successful and do not submit the purchase with it.

Before you start#

  1. Configure the NuPay or PayPal Wallet connection for the correct store and environment.
  2. Create an order and retain its order_token.
  3. For reusable PayPal accounts, authenticate the customer and send the user bearer token on consent requests.
  4. Read the payment-method response. For PayPal Vault, authorization.required: true and authorization.flow: "consent" indicate that the customer needs consent. Use the returned polling fields instead of hard-coding a cadence.
  5. Configure order.webhook_urls.notify_order so your backend receives consent state changes.

POST /merchants/orders/{order_token}/consent

The public API Gateway route intentionally does not include the internal /api/v1 service prefix.

curl --request POST \
  --url 'https://api.sandbox.deuna.io/merchants/orders/ORDER_TOKEN/consent' \
  --header 'X-API-KEY: YOUR_PRIVATE_API_KEY' \
  --header 'X-Store-Code: all' \
  --header 'Authorization: Bearer USER_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{
    "payment_method": "wallet",
    "payment_method_id": "MERCHANT_PAYMENT_METHOD_ID",
    "identity_document": "58188896454",
    "identity_document_type": "CPF"
  }'
FieldRequiredDescription
payment_methodRecommendedUse wallet. If omitted, DEUNA uses the payment method on the order.
payment_method_idRecommendedConnection identifier returned by the order payment-method response. It avoids ambiguity when more than one wallet connection is enabled.
identity_documentNuPayCustomer identity document. If omitted, DEUNA can derive it from the order address when present.
identity_document_typeNuPayDocument type, such as CPF. If omitted, DEUNA can derive it from the order address when present.

For an authenticated user, the bearer token lets DEUNA associate the successful consent with that user and connection. A guest consent remains order-bound.

Response envelope

JSON
{
  "id": "1625a32a-df4c-4d9b-aec1-4510b3625865",
  "type": "transaction.authentication.pending",
  "created": "1740608931",
  "data": {
    "request_id": "req_01JQ7X",
    "order": {
      "order_token": "7e975d44-a061-4d70-af0f-673f6ee56445",
      "transaction_id": "merchant-order-1042",
      "external_transaction_id": ""
    },
    "consent": {
      "id": "6fe9a045-9a46-4b25-8b60-d5a9586494c5",
      "status": "pending",
      "expires_at": "2026-10-02T18:30:00Z",
      "authorization_id": "provider-authorization-id",
      "redirect_url": "https://provider.example/approve"
    }
  }
}

Store data.consent.id, but drive the UI from data.consent.status. Open redirect_url only when it is present. NuPay can require approval in the provider app without returning a browser redirect.

Complete provider approval#

For PayPal Wallet, send the customer to data.consent.redirect_url. The provider returns through DEUNA's consent redirect route and DEUNA verifies the final provider state. If the customer cancels, the consent is marked as failed and must not be used for purchase.

For NuPay, instruct the customer to approve the request in the Nubank experience. The provider webhook updates the consent stored by DEUNA.

Never construct provider approval URLs or DEUNA redirect URLs yourself. Use the URLs in the response.

Read the latest status#

GET /merchants/orders/{order_token}/consent

curl --request GET \
  --url 'https://api.sandbox.deuna.io/merchants/orders/ORDER_TOKEN/consent?payment_method=wallet&payment_method_id=MERCHANT_PAYMENT_METHOD_ID' \
  --header 'X-API-KEY: YOUR_PRIVATE_API_KEY' \
  --header 'X-Store-Code: all' \
  --header 'Authorization: Bearer USER_TOKEN'

Use authorization.start_polling_after_in_seconds and authorization.polling_interval_in_seconds from the payment-method response when supplied. Stop polling as soon as the status is no longer pending, when expires_at is reached, or when the customer leaves the flow.

The GET response uses the same envelope as create consent. Always inspect both data.consent.status and data.error; a business-level terminal outcome can be represented in the envelope even when the HTTP request itself succeeded.

DEUNA sends consent updates to the order's webhook_urls.notify_order URL. Handle these event types:

Event typeMeaning
transaction.authentication.pendingAuthorization was created and still needs customer or provider action.
transaction.authentication.updatedAuthorization succeeded; the consent can be used.
transaction.authentication.failedAuthorization failed or the customer canceled.
transaction.authentication.expiredThe consent expired before it could be used.

Respond with 2xx quickly, deduplicate by the event id, and then fetch the latest consent if your processing depends on current state. Webhook delivery and GET polling complement one another; your checkout should tolerate either arriving first. See Webhooks.

NuPay

After success, request the order's payment methods and NuPay installment options. DEUNA uses the valid consent authorization while retrieving those options and while processing the wallet purchase. If the authorization has expired and the provider supports refresh, DEUNA attempts to refresh it.

PayPal Wallet

For an authenticated user, the approved PayPal account appears in stored_payment_methods. Send that stored method identifier as the purchase payment_method; DEUNA verifies that the consent belongs to the same user, merchant, and PayPal connection before using it.

Removing the stored wallet payment method also removes the associated reusable consent.

DELETE /users/payment-methods/{payment_method_id}/tokens/{payment_method}

Use payment_method_id for the PayPal connection identifier and payment_method for the stored method identifier returned in stored_payment_methods. This user-authenticated endpoint removes the wallet account at the provider and deletes the corresponding reusable consent in DEUNA.

curl --request DELETE \
  --url 'https://api.sandbox.deuna.io/users/payment-methods/MERCHANT_PAYMENT_METHOD_ID/tokens/STORED_PAYMENT_METHOD_ID' \
  --header 'Authorization: Bearer USER_TOKEN' \
  --header 'X-Merchant-ID: MERCHANT_ID'

A successful deletion returns 204 No Content. If the provider reports that the stored account is invalid during a purchase, DEUNA also removes the invalid reusable consent so it is not offered again.

Safe retry behavior#

  • Before creating a new consent, read the current state if the previous response was lost.
  • A still-valid pending or success consent is reused instead of creating another provider authorization.
  • Do not retry failed or expired indefinitely. Start a new customer-driven attempt after resolving the cause.
  • A 404 means DEUNA could not find consent for the order or user context.
  • A 400 can indicate invalid fields, an unsupported connection, a disabled guest flow, or a terminal provider result.
  • Keep private API keys and user tokens on trusted surfaces. Do not log request headers or provider authorization data.

Integration checklist#

  • The order, connection, currency, store, and environment match.
  • The identity document and type are available for NuPay.
  • The customer is authenticated before creating reusable PayPal consent.
  • The app supports provider redirect and app-approval experiences.
  • Polling uses the cadence returned by DEUNA and stops on terminal states.
  • notify_order accepts and deduplicates authentication events.
  • Purchase starts only after data.consent.status is success.
  • Failure, expiration, cancellation, and retry paths are tested in sandbox.