Refund purchase (marketplace)

Let us consider the case of 1 customer refund of a purchase including items from 2 sellers (seller A and seller B), with the total value of the refund being 100€, which consists of 10€ marketplace fees, 50€ seller payout to seller A and 40€ seller payout to seller B.

In such an event of a customer refund, the marketplace owner has to request the money back from the sellers. This can be done through the use of the Obligations API call. Once the obligation is captured, the seller payouts are refunded back to the escrow account.

Thus, the following payment flows need to be processed:

  1. Refund of seller payout (50€) from seller A to escrow
  2. Refund of seller payout (40€) from seller B to escrow
  3. Refund of marketplace fees (10€) from marketplace to escrow
  4. Refund of customer purchase (100€) from escrow to customer

Find wallet IDs

The wallet IDs of an account can be found by the account owner if they follow the steps below:

  1. Log in to Viva Wallet, demo or live , and select the required account.

  2. Click on Accounts in the left navigation.
    The wallet IDs are those indicated below in the Account ID column:

    Find wallet IDs
    You may have only the Primary wallet or have additional wallets set up for specific purposes.

Find transaction IDs

The transaction IDs generated after payment can be found as follows:

Redirect checkout

You can find the transaction ID in the URL displayed in the browser address bar after redirection to the Success URL:

Browser address bar

Obligation: Request information

post    /obligations/v1/obligations

The identity of the transfer recipient (escrow account) is implied in the credentials used for the API call’s authentication. The identity of the sender (seller) is acquired from the personID (Viva Wallet Merchant ID) defined as a body parameter in the API call.

Obligations can be captured only if the account has enough funds (the entire amount). Viva Wallet checks several times a day to see if funds are available otherwise the obligation status stays in a status of pending.

The required and optional fields for the request are shown in the table below.

Parameter Description Type Importance
amount In decimals rather than the smallest denomination of the currency (0.6 pounds instead of 60 pence). decimal Required
personId Seller merchant ID from which the refund payback is being requested. long Required
walletId Use null unless there is a wallet other than the default primary one that’s being used by the seller for their transactions. long Optional
description A string with extra information you want to show in the transaction once the obligation is captured. string Optional
currencyCode The 3-digit currency code of the transaction. Should be set to the same currency as the Viva Wallet accounts involved in the obligation call. integer Required

Balance Transfer: Request information

post    /api/wallets/{walletId}/balancetransfer/{targetWalletId}

The required and optional fields for the request are shown in the table below.

Parameter Description Type Importance
walletId Source ID of the wallet from which you wish to make the transfer. Displayed as Account ID under Accounts in the Viva Wallet banking app. long Required
targetWalletId Destination ID of the wallet to which you wish to make the transfer. Displayed as Account ID under Accounts in the Viva Wallet banking app. long Required
amount Transfer amount in the smallest denomination of your account currency. long Required
description Some text to summarize the transfer reason. Appears on target account statement. string Optional
saleTransactionId The Viva Wallet transaction ID generated during checkout (as a reference only). GUID Optional

Step 1: Refund of 50€ from seller A to escrow

The below examples use OAuth 2 for authentication.

For this example you need first to make sure that you have correctly identified the person ID of seller A. This is identical to seller A’s merchant ID. You need to ask the seller to provide you with this information.

Next, you need to generate a bearer token using the Native Checkout v2 client credentials from the escrow account.

Lastly, you need to establish the wallet ID being used by seller A. They can find this easily in the Viva Wallet banking app. If the Primary (default) wallet is being used, you can use “null” as the entry for the walletId parameter. You need to ask the seller to provide you with this information.

Note: The value of the currencyCode parameter needs to match that of the escrow account and the seller account, otherwise an error response will be returned.

Example request

curl -L -X POST 'https://demo-api.vivapayments.com/obligations/v1/obligations' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer [escrow account bearer token]' \
--data-raw '{
    "amount": "50.00",
    "personId": "[seller A account merchant ID]",
    "walletId": "[seller A wallet ID]",
    "description": "[This is an example]",
    "currencyCode": "826"
}'

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://demo-api.vivapayments.com/obligations/v1/obligations',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS =>'{
    "amount": "50.00",
    "personId": "[seller A account merchant ID]",
    "walletId": "[seller A wallet ID]",
    "description": "[This is an example]",
    "currencyCode": "826"
}',
  CURLOPT_HTTPHEADER => array(
    'Content-Type: application/json',
    'Authorization: Bearer [escrow account bearer token]'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

Run in Postman

Example response

{
    "captureId": null,
    "statusId": "A",
    "obligationId": "d1539512-95dd-44d6-b5d5-78c8b4f53839",
    "cancellationId": null,
    "created": "2020-11-25T17:26:13.681595+02:00",
    "completed": null,
    "walletTransactionSubTypeId": 159
}

Step 2: Refund of 40€ from seller B to escrow

Use OAuth 2 for authentication.

For this example you need first to make sure that you have correctly identified the person ID of the seller B account. This is identical to seller B’s merchant ID. You need to ask the seller to provide you with this information.

Next, you need to generate a bearer token using the Native Checkout v2 client credentials from the escrow account.

Lastly, you need to establish the wallet ID being used by seller B. They can find this easily in the Viva Wallet banking app. If the Primary (default) wallet is being used, you can use “null” as the entry for the walletId parameter. You need to ask the seller to provide you with this information.

Note: The value of the currencyCode parameter needs to match that of the escrow account and the seller account. Anything different will cause an error.

Example request

curl -L -X POST 'https://demo-api.vivapayments.com/obligations/v1/obligations' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer [escrow account bearer token]' \
--data-raw '{
    "amount": "40.00",
    "personId": "[seller B merchant ID]",
    "walletId": "[seller B wallet ID]",
    "description": "[This is an example]",
    "currencyCode": "826"
}'

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://demo-api.vivapayments.com/obligations/v1/obligations',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS =>'{
    "amount": "40.00",
    "personId": "[seller B merchant ID]",
    "walletId": "[seller B wallet ID]",
    "description": "[This is an example]",
    "currencyCode": "826"
}',
  CURLOPT_HTTPHEADER => array(
    'Content-Type: application/json',
    'Authorization: Bearer [escrow account bearer token]'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

Run in Postman

Example response

{
    "captureId": null,
    "statusId": "A",
    "obligationId": "d1539512-95dd-44d6-b5d5-78c8b4f53839",
    "cancellationId": null,
    "created": "2020-11-25T17:26:13.681595+02:00",
    "completed": null,
    "walletTransactionSubTypeId": 159
}

Step 3: Refund of 10€ from marketplace to escrow

Use basic auth for authentication.

You also have to ensure that you enable transfers between accounts in the Viva Wallet banking app (for the marketplace account only). To do this:

  1. Log in to Viva Wallet, demo or live , and select the required account.

  2. Go to Settings > API Access.

  3. Select the Allow transfers between accounts checkbox as shown below:

    Allow transfers between accounts
    The new setting is saved automatically.

For this example you need first to find the wallet IDs of your marketplace account and escrow account. The marketplace owner has access to both the escrow account and marketplace account, so it is straightforward to find the IDs for these wallets.

Example request

curl -L -X POST 'https://demo.vivapayments.com/api/wallets/{marketplace wallet ID}/balancetransfer/{escrow wallet ID}' \
-H 'Content-Type: application/json' \
-H 'Authorization: Basic [Base64-encoded Merchant ID and API key (marketplace account)]' \
--data-raw '{
  "amount": "1000",
  "description": "[Optional text to show on account statement]",
  "saleTransactionId": "[Optional transaction ID for the related sale]"
}'

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://demo.vivapayments.com/api/wallets/{marketplace wallet ID}/balancetransfer/{escrow wallet ID},
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS =>'{
  "amount": "1000",
  "description": "[Optional text to show on account statement]",
  "saleTransactionId": "[Optional transaction ID for the related sale]"
}',
  CURLOPT_HTTPHEADER => array(
    'Content-Type: application/json',
    'Authorization: Basic [Base64-encoded Merchant ID and API key (marketplace account)]'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

Run in Postman

Example response

{
    "DebitTransactionId": "b8ff48b5-a2ac-4c95-a4fe-f4c1c9f5741b", //refers to marketplace account
    "CreditTransactionId": "9a85d019-6ec6-4e27-be45-84ef320b8d3e" //refers to escrow account
}

Step 4: Refund of 100€ from escrow to customer

This is done through the Viva Wallet banking app or via a simple Cancel transaction API call (including the amount) using basic auth.

Example request

curl -L -X DELETE 'https://demo.vivapayments.com/api/transactions/[transactionId]/?amount=10000 \
-H 'Authorization: Basic [Base64-encoded Merchant ID and API key (escrow account)]'

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://demo.vivapayments.com/api/transactions/[transactionId]/?amount=10000',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'DELETE',
  CURLOPT_HTTPHEADER => array(
    'Authorization: Basic [Base64-encoded Merchant ID and API key (escrow account)]'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

Run in Postman

Example response

A successful refund is identified by “statusId”:”F” (finished or finalised) in the response as shown in the example below.

{
    "Emv": null,
    "Amount": 100.00,
    "StatusId": "F",
    "RedirectUrl": null,
    "CurrencyCode": "826",
    "TransactionId": "1289e200-6891-4739-afe5-5c13e839545b",
    "ReferenceNumber": 839335,
    "AuthorizationId": "839335",
    "RetrievalReferenceNumber": "109110839335",
    "Loyalty": null,
    "ThreeDSecureStatusId": 2,
    "ErrorCode": 0,
    "ErrorText": null,
    "TimeStamp": "2021-04-01T13:48:23.5665277+03:00",
    "CorrelationId": null,
    "EventId": 0,
    "Success": true
}