> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gr4vy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# dLocal - UPI

> Configure UPI via dLocal as a payment method in Gr4vy.

dLocal is a global payments platform that helps you accept local payment methods and cards across emerging markets.

UPI (Unified Payments Interface) is India's instant payment system that enables real-time bank-to-bank transfers through mobile devices.

## Setup

Please follow the [common dLocal instructions](./dlocal) to get set up with UPI.

Next, make sure to enable UPI as a payment method on your configured account.

## Features

* **Tokenization** - Save payment methods for future use
* **Delete tokens** - Remove stored payment methods
* **Partial refunds** - Refund a portion of the captured amount
* **Refunds** - Full refund support
* **Settlement reporting** - Access to settlement reports
* **Transaction sync** - Automatic transaction status synchronization

## Supported countries

dLocal supports transactions from buyers in `IN`.

## Supported currencies

dLocal supports processing payments in `INR`.

## Limitations

* **Capture** - Delayed capture is not supported
* **Void** - Transaction void is not supported

## Integration

For UPI, the default integration is through a redirect to a hosted payments page.

Start by creating a new transaction with the following required fields.

<CodeGroup>
  ```csharp C# theme={"system"}
  var transaction = await client.Transactions.CreateAsync(
      transactionCreate: new TransactionCreate()
      {
          Amount = 1299,
          Currency = "INR",
          Country = "IN",
          PaymentMethod =
              TransactionCreatePaymentMethod.CreateCheckoutSessionWithUrlPaymentMethodCreate(
                  new RedirectPaymentMethodCreate()
                  {
                      Method = "upi",
                      RedirectUrl = "https://example.com/callback",
                  }
              ),
      }
  );
  ```

  ```go Go theme={"system"}
  amount := int64(1299)
  currency := "INR"
  country := "IN"
  method := "upi"
  redirectUrl := "https://example.com/callback"

  redirectPaymentMethodCreate := components.RedirectPaymentMethodCreate{
      Method: method,
      RedirectUrl: redirectUrl,
  }
  paymentMethod := components.CreateTransactionCreatePaymentMethodRedirectPaymentMethodCreate(redirectPaymentMethodCreate)

  transactionCreate := components.TransactionCreate{
      Amount:        amount,
      Currency:      currency,
      Country:       &country,
      PaymentMethod: &paymentMethod,
  }

  transaction, err := client.Transactions.Create(ctx, transactionCreate, nil, nil)
  ```

  ```java Java theme={"system"}
  CreateTransactionResponse transactionResponse = gr4vyClient.transactions().create()
      .transactionCreate(TransactionCreate.builder()
          .amount(1299L)
          .currency("INR")
          .country("IN")
          .paymentMethod(TransactionCreatePaymentMethod.of(RedirectPaymentMethodCreate.builder()
              .method("upi")
              .redirectUrl("https://example.com/callback")
              .build()))
          .build())
      .call();

  Transaction transaction = transactionResponse.transaction().orElse(null);
  ```

  ```php PHP theme={"system"}
  $transactionCreate = new TransactionCreate(
      amount: 1299,
      currency: 'INR',
      country: 'IN',
      paymentMethod: new RedirectPaymentMethodCreate(
          method: 'upi',
          redirectUrl: 'https://example.com/callback'
      )
  );
  $response = self::$sdk->transactions->create($transactionCreate);
  $transaction = $response->transaction;
  ```

  ```python Python theme={"system"}
  transaction: models.Transaction = client.transactions.create(
      amount=1299,
      currency="INR",
      country="IN",
      payment_method={
          "method": "upi",
          "redirect_url": "https://example.com/callback",
      }
  )
  ```

  ```ts TypeScript theme={"system"}
  const transaction = await gr4vy.transactions.create({
      amount: 1299,
      currency: "INR",
      country: "IN",
      paymentMethod: {
          method: "upi",
          redirectUrl: "https://example.com/callback"
      }
  })
  ```
</CodeGroup>

After the transaction is created, the API response includes `payment_method.approval_url` and the status is set to `buyer_approval_pending`.

Redirect the buyer to the `approval_url` so they can complete the payment. After approval the buyer is redirected to the `redirect_url` you provided when creating the transaction. Do not rely solely on the redirect - either poll the transaction or (recommended) rely on webhooks to detect the final status (for example `capture_succeeded` or failure states).

## Recurring transactions

Recurring UPI payments are not confirmed in real-time.
A transaction takes at least 24 hours (up to 48 hours) to be confirmed due to a mandatory upcoming payment notification rule in India.
As a result, the UPI integration waits for an asynchronous callback (webhook) to receive the final payment status.
The same process applies to the tokenization of a payment method, which only works for recurring or installments transactions.

You can specify the payment frequency using the [dLocal UPI connection options](https://docs.gr4vy.com/reference/transactions/new-transaction#body-connection-options-dlocal-upi).
The example below demonstrates how to configure a monthly payment that recurs for one year.

```
  "connectionOptions": {
    "dlocal-upi": {
      "wallet": {
        "recurring_info": {
          "subscription_end_at": "20261016",
          "subscription_frequency": 1,
          "subscription_frequency_unit": "MONTH",
          "subscription_start_at": "20251016"
        }
      }
    }
  }
```

## Usage with Embed

When storing a UPI payment method with Embed, dLocal requires it to be set up as a recurring transaction.
You can do this by setting the `paymentSource` to `recurring`.
If this isn't configured correctly, the transaction errors with "Payment method tokenization is only supported for recurring transactions.".

## Sandbox testing

When testing dLocal UPI in a sandbox environment, you are redirected to an enrollment experience for recurring transactions. This process may not return immediately and can take several minutes to begin processing the transaction.
You may need to refresh the approval URL multiple times before the transaction is successfully initiated.
