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

# Upgrade Your Virtual Account Integration

> Update an existing Virtual Account integration before the new application flow takes effect in Production.

Use this guide if your integration already calls Create Virtual Account or processes Virtual Account webhooks. The new behavior is available in Sandbox from **August 13, 2026** and takes effect in Production on **September 3, 2026**.

<Warning>
  Complete this upgrade before the Production date. Both the Create success response and Virtual Account webhook data are changing.
</Warning>

## Changes at a glance

| Integration area     | Previous behavior                                              | New behavior                                                                 |
| -------------------- | -------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| Create success       | HTTP `202` with `message` and `request_id`                     | HTTP `200` with the accepted application in `data`                           |
| Request correlation  | `request_id` or `x-request-id`                                 | `application_id`                                                             |
| Country and currency | No application country; currency could contain multiple values | One required `country` and one required `currency`                           |
| Receiving method     | One method selected by the request                             | Send `LOCAL` or `SWIFT`, or omit `payment_method` to evaluate both           |
| Result handling      | No method-level application results                            | Process every entry in `results[]`                                           |
| Application queries  | No application query endpoints                                 | Use List Applications and Retrieve Application                               |
| Webhooks             | An event could represent one issued bank-detail record         | Events represent the whole application and use `public_version` for ordering |

The Create path remains `POST /v1/virtual/accounts`.

## 1. Update the Create request

Keep sending the required `x-idempotency-key`. Change your request builder to:

1. Add the required two-letter `country`.
2. Send one three-letter `currency` value.
3. Send `payment_method` as `LOCAL` or `SWIFT`, or omit it to evaluate both methods. Do not send `ALL` or `AUTO`.
4. Treat `nickname` as optional.
5. Remove logic that uses `x-request-id` for this endpoint.

For a connected account, continue to send its account ID in `x-on-behalf-of`. See [Create Virtual Account](/global-account/v1.6/api-reference/create-virtual-account) for the request schema and [supported combinations](/global-account/v1.6/guide/virtual-account-api-lifecycle#choose-what-to-request) for valid values.

When retrying after a network failure, send the same request for the same account with the same `x-idempotency-key`. Use a new key when any application input changes.

## 2. Replace the Create success response

Parse HTTP `200` as an accepted application. It does not mean bank details are ready.

Remove parsing of `message` and `request_id`. Instead:

1. Store `data.account_id` and `data.direct_id` with the application.
2. Store `data.application_id`.
3. Store `data.public_version`.
4. Process every entry in `data.results[]` and identify it by `payment_method`.
5. Use bank details only when the result is `COMPLETED` and the individual record is `ACTIVE`.

If `payment_method` is omitted, one result can be `SKIPPED` while another is `SUBMITTED`. Do not treat the top-level application status as the status of every method.

## 3. Add application queries

Add these endpoints to your integration:

* [List Virtual Account Applications](/global-account/v1.6/api-reference/list-virtual-account-applications) discovers and reconciles applications. `page_number` and `page_size` are required.
* [Retrieve Virtual Account Application](/global-account/v1.6/api-reference/retrieve-virtual-account-application) returns the latest full details for one `application_id`.

Keep [List Virtual Accounts](/global-account/v1.6/api-reference/list-virtual-accounts) for issued bank details. It does not list pending applications.

## 4. Update the webhook consumer

Handle all three application event types:

| Event                    | Required action                                                                      |
| ------------------------ | ------------------------------------------------------------------------------------ |
| `virtual.account.create` | Store the accepted application. Do not assume it arrives after the Create response.  |
| `virtual.account.update` | Apply the new data only when `public_version` is higher than the version you stored. |
| `virtual.account.closed` | Apply the final `CLOSED` data and stop using all related bank details.               |

Keep your existing signature verification and acknowledgement flow. Change correlation and ordering logic to:

1. Deduplicate deliveries by `event_id`.
2. Associate the event with the account in `data.account_id`; use `data.direct_id` to identify its main account when applicable.
3. Locate the application by `data.application_id`.
4. Apply only a higher `data.public_version`.
5. Process every result after applying the event.
6. Call Retrieve when a version is missing or delivery appears out of order.

See [Virtual Account Application Webhooks](/global-account/v1.6/webhooks/virtual-account-create-update) for event timing, examples, and recovery behavior.

## 5. Separate request errors from later failures

A synchronous Create `400` means no application was created and no application webhook will follow. Correct the request or account setup before trying again.

After HTTP `200`, a receiving method can later become `FAILED`. In that case, process the `virtual.account.update` event and use `results[].error.code` to decide the next action. See [Integrate Virtual Accounts with the API](/global-account/v1.6/guide/virtual-account-api-lifecycle#handle-errors) for error codes and actions.

## Sandbox checklist

Before Production rollout, verify that your integration can:

* Send one supported `country` and `currency`, with an optional `payment_method`.
* Retry an identical request with the same `x-idempotency-key` and retain one `application_id`.
* Reject reuse of the key for different application input.
* Parse HTTP `200` and process every entry in `results[]`.
* Handle `SKIPPED` and `SUBMITTED` results in the same application.
* Store and compare `application_id + public_version`.
* List applications and retrieve the latest details.
* Accept `virtual.account.create` before or after the Create response.
* Associate application events with the correct account using `account_id` and `direct_id`.
* Apply `COMPLETED`, `FAILED`, and `CLOSED` data without relying on delivery order.
* Use only `ACTIVE` bank details and stop using `CLOSED` records, even when `close_reason` is empty.
* Stop waiting for a webhook after a synchronous Create error.

After the checklist passes, use [Integrate Virtual Accounts with the API](/global-account/v1.6/guide/virtual-account-api-lifecycle) as the ongoing integration guide.
