cURL php javascript java

API Reference

Wave Business APIs provide a programmatic means to work with your Wave business account. Using these REST APIs, you can collect money and check the balance on your wallet. To use these APIs, you need a Wave business account.

For an overview and quick start instructions, see our Getting Started with the Wave Checkout API guide.

Base URL

All the endpoint paths referenced in the API document are relative to a base URL, https://api.wave.com.

Authentication

Authenticating to the API is done via API keys. These keys are bound to a single business wallet and can only interact with it.

If you need to interact with more than one wallet in your network, then you will have to obtain one key per wallet.

Each request must be sent over HTTPS and contain an authorization header specifying the bearer scheme with the api key:

Authorization: Bearer wave_sn_prod_YhUNb9d...i4bA6

Note that the actual key is much longer but for documentation purposes most of the characters have been replaced by an ellipses.

Obtaining your API key

You can manage API keys in the developer's section in the Wave Business Portal. You can create, view, and revoke keys, and define which specific APIs each key has access to.

Dev Portal

When you create a new API key, you will only see the full key once. Make sure you copy it without missing any characters, since it will be masked afterwards for security reasons.

Create API Key

Wave doesn't know your full key, but if you contact API support we can identify them by the last 4 letters that you see displayed in the business portal.

Error codes

In the authentication phase, one of the following errors can cause your request to return early:

Status Code Descriptions
401 missing-auth-header Your request should include an HTTP auth header.
401 invalid-auth Your HTTP auth header can't be processed.
401 api-key-not-provided Your request should include an API key.
401 no-matching-api-key The key you provided doesn't exist in our system.
401 api-key-revoked Your API key has been revoked.
403 invalid-wallet Your wallet can't be used in this particular API.
403 disabled-wallet Your wallet has been temporarily disabled. You should still be able to use the endpoint to check your balance.

Rate limiting

Wave APIs are rate limited to prevent abuse that would degrade performance for all users. If you send many requests in a short period of time, you may receive 429 error responses.

Requests

Here's an example of how you can construct a POST request with Authorization and Content-Type headers and JSON data:

curl \
-X POST \
-H 'Authorization: Bearer wave_sn_prod_YhUNb9d...i4bA6' \
-H 'Content-Type: application/json' \
-d '{
      "amount": "1000",
      "currency": "XOF",
      "error_url": "https://example.com/error",
      "success_url": "https://example.com/success"
    }' \
https://api.wave.com/v1/checkout/sessions
const axios = require('axios');

axios.post('https://api.wave.com/v1/checkout/sessions', {
  amount: "1000",
  currency: "XOF",
  error_url: "https://example.com/error",
  success_url: "https://example.com/success"
}, {
  headers: {
    'Authorization': 'Bearer wave_sn_prod_YhUNb9d...i4bA6',
    'Content-Type': 'application/json'
  }
})
.then(response => {
  console.log(response.data);
})
.catch(error => {
  console.error(error);
});
$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://api.wave.com/v1/checkout/sessions",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => json_encode([
    "amount" => "1000",
    "currency" => "XOF",
    "error_url" => "https://example.com/error",
    "success_url" => "https://example.com/success"
  ]),
  CURLOPT_HTTPHEADER => [
    "Authorization: Bearer wave_sn_prod_YhUNb9d...i4bA6",
    "Content-Type: application/json"
  ],
]);

$response = curl_exec($curl);

curl_close($curl);
echo $response;
import okhttp3.*;
import org.json.JSONObject;

public class Main {
  public static void main(String[] args) {
    OkHttpClient client = new OkHttpClient().newBuilder().build();
    MediaType mediaType = MediaType.parse("application/json");
    RequestBody body = RequestBody.create(mediaType, new JSONObject()
      .put("amount", "1000")
      .put("currency", "XOF")
      .put("error_url", "https://example.com/error")
      .put("success_url", "https://example.com/success")
      .toString());
    Request request = new Request.Builder()
      .url("https://api.wave.com/v1/checkout/sessions")
      .method("POST", body)
      .addHeader("Authorization", "Bearer wave_sn_prod_YhUNb9d...i4bA6")
      .addHeader("Content-Type", "application/json")
      .build();
    try {
      Response response = client.newCall(request).execute();
      System.out.println(response.body().string());
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Wave API requests use HTTP bearer authorization and, for those with a body, JSON format and UTF-8 encoding. All requests should be sent with HTTPS.

Methods

Wave API requests use the HTTP GET or POST methods.

The GET method is used to retrieve resources. GET requests are idempotent and will not change any data on the server.

The POST method is used to create new resources.

Headers

For authentication, the Authorization header must be included in the request. The value consists of the auth scheme, Bearer followed by the api key:

Authorization: Bearer <API key>

For requests which include a body, the Content-Type header must specify that the body is JSON:

Content-Type: application/json

Body

Some Wave API requests include data. That data must be in JSON format and use UTF-8 encoding.

Responses

Wave API responses use HTTP status codes to indicate whether a request has been completed successfully. 2xx codes indicate that the request was successful received, understood and accepted. 4xx codes signal a problem with the request from the client and 5xx codes indicate a problem on the server end. See Errors for more information about error responses.

For a response to a successful API request, the message body contains information provided by the server in JSON format (using UTF-8 encoding).

For a response to an unsuccessful request, the message body includes details about the error in JSON format (using UTF-8 encoding). Minimally, this includes a short error code and a longer user-readable message describing the reason for the failure.

Errors

When an API request cannot be completed successfully, the response provides information about the failure in the message body and in the HTTP status code.

Error details

Here's what the message body of a response to an invalid request might look like:

{
  "code": "request-validation-error",
  "message": "Request invalid",
  "details": [{
    "loc": ["payments", 1, "mobile"],
    "msg": "field required"
  }]
}

In response to unsuccessful requests, Wave provides details about the error in the message body. This includes, minimally, a short code and longer user-readable message describing the error. For validation errors, Wave may also provide details of what failed including the field that failed validation and the problem with it.

Status codes

The general reason for the failure is reflected in the HTTP response status code. 4xx codes signal a problem with the request from the client and 5xx codes indicate a problem on the server end. Specific details of the problem are provided in the message body.

Some of the status codes we return are listed below.

Code Title Descriptions
400 Bad Request The server cannot process the request because it is badly formed.
401 Unauthorized The API key is invalid.
403 Forbidden The API key doesn't have appropriate permissions for the request.
404 Not Found You requested an object or page that could not be found.
422 Unprocessable Entity The request is properly formed but the server is unable to process the contents.
429 Too Many Requests The rate limit was exceeded i.e. the server received too many requests in a given period of time.
500 Internal Server Error The server encountered an error. Try again later.
503 Service Unavailable The server is unable to handle the request due to a temporary overload or scheduled maintenance. Try again later.

Data formats

Some of the parameters in Wave API requests or attributes in API objects follow specific data formats.

Amounts

All amounts are represented as strings. When the amount includes decimal places, the separator is a period (.). The following rules apply to valid amounts:

Currency

Standard ISO 4217 three-letter codes in upper case are used to specify currency. The code for the West African Franc is XOF. Decimal places are not allowed for XOF currency amounts.

Timestamps

Timestamp values follow the ISO 8601 standard. Timestamps that we provide in API objects will be of the form YYYY-MM-DDThh:mm:ssZ where the Z indicates the UTC time zone.

Transaction Type

Name Description
merchant_payment A payment from a customer to a business.
merchant_payment_refund A refund of a merchant payment.
api_checkout A payment from a customer to a business made through the Checkout API
api_checkout_refund A refund of a checkout payment.
api_payout A payment from a business to a customer, made through the Payout API
api_payout_reversal A reversal of a business payment.
bulk_payment A payment from a business to a customer, made through the Bulk Payments portal.
bulk_payment_reversal A reversal of a business payment.
b2b_payment A payment from a business to another business.
b2b_payment_reversal A reversal of payment from a business to another business.
merchant_sweep A reversal of payment from a business to another business.

Webhooks

Visit the Webhooks documentation

Balance API

ENDPOINTS:
GET /v1/balance

The Balance API provides a programmatic means to retrieve the balance on your wallet.

The Balance object

BALANCE OBJECT

{
  "amount": "10245",
  "currency": "XOF"
}

The Balance object represents the amount of money in a Wave wallet.

Attributes


amount string
Balance amount.

currency currency
Three-letter ISO 4217 currency code.

Retrieve balance

GET /v1/balance

curl \
-H 'Authorization: Bearer wave_sn_prod_YhUNb9d...i4bA6' \
https://api.wave.com/v1/balance
$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://api.wave.com/v1/balance",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => [
    "Authorization: Bearer wave_sn_prod_YhUNb9d...i4bA6"
  ],
]);

$response = curl_exec($curl);

curl_close($curl);
echo $response;
const axios = require('axios');

axios.get('https://api.wave.com/v1/balance', {
  headers: {
    'Authorization': 'Bearer wave_sn_prod_YhUNb9d...i4bA6'
  }
})
.then(response => {
  console.log(response.data);
})
.catch(error => {
  console.error(error);
});
HttpResponse<String> response = Unirest.get("https://api.wave.com/v1/balance")
.header("Authorization", "Bearer wave_sn_prod_YhUNb9d...i4bA6")
.asString();

System.out.println(response.getBody());

Retrieves the current balance of the account associated with the API key used to make the request.

Parameters


No parameters.

Returns


Returns a balance object for the account associated with the API key used to make the request.

Retrieve your transactions

GET /v1/transactions

curl -X GET \
  --url https://api.wave.com/v1/transactions?date=2022-10-25 \
  -H 'Authorization: Bearer wave_sn_prod_YhUNb9d...i4bA6'
$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://api.wave.com/v1/transactions?date=2022-10-25",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => [
    "Authorization: Bearer wave_sn_prod_YhUNb9d...i4bA6"
  ],
]);

$response = curl_exec($curl);

curl_close($curl);
echo $response;
const axios = require('axios');

axios.get('https://api.wave.com/v1/transactions?date=2022-10-25', {
  headers: {
    'Authorization': 'Bearer wave_sn_prod_YhUNb9d...i4bA6'
  }
})
.then(response => {
  console.log(response.data);
})
.catch(error => {
  console.error(error);
});
HttpResponse<String> response = Unirest.get("https://api.wave.com/v1/transactions?date=2022-10-25")
.header("Authorization", "Bearer wave_sn_prod_YhUNb9d...i4bA6")
.asString();
System.out.println(response.getBody());

Example response

{
  "page_info": {
    "start_cursor": null,
    "end_cursor": "TFRfdUZ1MGoyMzVKemtz",
    "has_next_page": true
  },
  "date": "2022-11-07",
  "items": [
    {
      "timestamp": "2022-11-07T14:41:15Z",
      "transaction_id": "T_V3TFOUE7VU",
      "amount": "99",
      "fee": "1",
      "currency": "XOF",
      "counterparty_name": "Mame Diop",
      "counterparty_mobile": "+221761110000"
    },
    {
      "timestamp": "2022-11-07T14:42:06Z",
      "transaction_id": "T_2YJNPWMCIY",
      "amount": "99",
      "fee": "1",
      "currency": "XOF",
      "counterparty_name": "Fatou Ndiaye",
      "counterparty_mobile": "+221761110001"
    },
    {
      "timestamp": "2022-11-07T14:42:41Z",
      "transaction_id": "T_2YJNPWMCIY",
      "amount": "-99",
      "fee": "-1",
      "currency": "XOF",
      "is_reversal": true
    },
    {
      "timestamp": "2022-11-07T14:42:54Z",
      "transaction_id": "pt-1azcvz4081002",
      "amount": "-101",
      "fee": "1",
      "currency": "XOF",
      "counterparty_name": "Moustapha Mbaye",
      "counterparty_mobile": "+221761110519"
    },
    {
      "timestamp": "2022-11-07T14:43:00Z",
      "transaction_id": "pt-1azcw0qkg1004",
      "amount": "-121",
      "fee": "1",
      "currency": "XOF",
      "counterparty_name": "Moustapha Mbaye",
      "counterparty_mobile": "+221761110519"
    },
    {
      "timestamp": "2022-11-07T14:43:14Z",
      "transaction_id": "pt-1azcw0qkg1004",
      "amount": "121",
      "fee": "1",
      "currency": "XOF",
      "counterparty_name": "Moustapha Mbaye",
      "counterparty_mobile": "+221761110519",
      "is_reversal": true
    }
  ]
}

Returns a list of transactions of your account for a given day. Uses pagination if the number of transactions exceeds 1000 entries. The transactions are ordered from older to newer.

Request parameters

URL parameters are passed in the form of https://api.wave.com/v1/transactions?date=value1&after=value2.

Name Type Description
date URL parameter (optional) Which day to fetch transactions for. Returns the current day's transactions if not specified.
after URL parameter (optional) The pointer of the page to fetch. This is an opaque string, and generally you just pass it the end_cursor of the previous page, as returned in the page_info object. See pagination.

Return attributes

Key Type Description
timestamp Timestamp The execution time and date of the transaction.
transaction_id String A unique identifier for a transaction. Up to 20 characters.
transaction_type Transaction Type The type of transaction.. Can be empty.
amount String The amount difference that this transaction had on your account.
fee String The fee for the transaction.
balance String The wallet's balance after this transaction was executed.
currency Currency code The 3-letter ISO 4217 currency code of the transaction amount.
is_reversal Boolean (optional) Marked true if this is a reversal or refund of a previous transaction.
counterparty_name String (optional) The name of the counterparty (sender or receiver) of the transaction.
counterparty_mobile String (optional) The mobile number of the counterparty (sender or receiver) of the transaction.
counterparty_id String (optional) The identifier of the counterparty in B2B payments.
business_user_name String (optional) The name of the business user involved in the transaction. This is for example the shop assistant/business user, or the depositor for an agent transaction.
business_user_mobile String (optional) The mobile number of the business user involved in the transaction.
employee_id String (optional) The employee ID associated with the busienss user involved in the transaction.
client_reference String (optional) A unique string that you (optionally) provided when submitting the transaction.
payment_reason String (optional) A payment reason or message that you (optionally) provided when submitting the transaction.
checkout_api_session_id String (optional) If this payment is linked to a Checkout API session, this is its ID.
batch_id String (optional) The batch ID if this transaction is part of a bulk payment.
aggregated_merchant_id String (optional) The ID of the aggregated merchant this transaction is assigned to. Only applicable if you're an aggregator processing payments for a merchant that is integrating via your services.
aggregated_merchant_name String (optional) The name of the aggregated merchant this transaction is assigned to. Only applicable if you're an aggregator processing payments for a merchant that is integrating via your services.
custom_fields JSON Object (optional) A key-value map of any custom fields related to this payment.

Refund a transaction

POST /v1/transactions/:transaction_id/refund

curl -X POST \
  -L https://api.wave.com/v1/transactions/T_VZSWJF5MMQ/refund \
  -H 'Authorization: Bearer wave_sn_prod_YhUNb9d...i4bA6'

Example response

HTTP 200 OK

With this endpoint you can reverse a transaction, including fees. You don't need to indicate a reason, you can simply refund your customers any time you deem necessary.

Request parameters

There are no parameters necessary in the request body. Note that the transaction_id is passed in the request path.

Response body

There is no response body. The status code will inform you whether a refund was successful (200), or the transaction doesn't exist (404), or something else went wrong (500).

Pagination

Example page info object

"page_info": {
  "start_cursor": null,
  "end_cursor": "TFRfRGxVVlN5eHhPRmhk",
  "has_next_page": true
}

If the number of items of an API request is too many to return in a single request, then the results are paginated. The cutoff amount depends on the API, for example the Balance API transactions export is limited to 1000 transactions.

Name Type Description
start_cursor URL parameter The opaque id of the current page.
end_cursor URL parameter The opaque id of the next page. Generally you simply pass this to the next request as the after URL parameter.
has_next_page Boolean A flag to let you know there are more items to fetch.

You can simply iterate through the pages by calling https://api.wave.com/v1/<endpoint>?after=<end_cursor>.

Checkout API

ENDPOINTS:

POST /v1/checkout/sessions
GET /v1/checkout/sessions/:id
GET /v1/checkout/sessions
GET /v1/checkout/sessions/search
POST /v1/checkout/sessions/:id/expire
POST /v1/checkout/sessions/:id/refund

The Checkout API provides a programmatic means to allow you to prompt users from a website or a mobile app to send payments.

The Checkout Session object

CHECKOUT SESSION OBJECT

{
  "id": "cos-18qq25rgr100a",
  "amount": "1000",
  "checkout_status": "complete",
  "client_reference": null,
  "currency": "XOF",
  "error_url": "https://example.com/error",
  "last_payment_error": null,
  "business_name": "Papa's Penguins",
  "payment_status": "succeeded",
  "transaction_id": "TDH5TEWTLFE",
  "aggregated_merchant_id": "am-7lks22ap113t4",
  "success_url": "https://example.com/success",
  "wave_launch_url": "https://pay.wave.com/c/cos-18qq25rgr100a",
  "when_completed": "2021-12-08T10:15:32Z",
  "when_created": "2021-12-08T10:13:04Z",
  "when_expires": "2021-12-09T10:13:04Z"
}

The Checkout Session object contains details about the requested payment and its status.

Attributes


id string
Unique identifier for the Checkout Session object. Up to 20 characters.

amount string
Total amount to collect from the customer (gross of fees).

checkout_status enum
The status of the checkout, one of open, complete, or expired.

client_reference string (optional)
A unique string which can be used to correlate the checkout session and subsequent payment with your system. You provide this value in the request to create a checkout session.

currency string
Three-letter ISO 4217 currency code.

error_url string
The URL the customer will be directed to if an error occurs on a payment attempt.

last_payment_error hash (optional)
The reason for the last failed payment attempt. Can only be populated when the payment_status is processing or cancelled. Contains the following fields:

business_name string
The name of the business as it will be shown to the customer.

payment_status enum
The status of the associated payment, one of processing, cancelled, or succeeded.

aggregated_merchant_id: string (optional)
The aggregated merchant id used for this checkout transaction.

restrict_payer_mobile: string (optional)
This checkout session can only be paid by the Wave account with this number. Note: this field was previously called enforce_payer_mobile, so both are currently returned.

success_url string
The URL the customer will be directed to if the payment succeeds.

transaction_id string
A Wave transaction ID that is also visible in the user's app.

wave_launch_url string
A URL which will open the Wave app to initiate the checkout or give instructions for completing the checkout if Wave is not installed on the device.

when_completed ISO 8601 timestamp
UTC time at which the checkout session either succeeded or expired. Not populated when the checkout_status is open.

when_created ISO 8601 timestamp
UTC time that the checkout session was created.

when_expires ISO 8601 timestamp
UTC time at which the checkout session will expire. By default, checkout sessions expire 30 minutes after their creation. After expiration, payments will not be accepted for the checkout session.

Create a checkout session

POST /v1/checkout/sessions

curl \
-X POST \
-H 'Authorization: Bearer wave_sn_prod_YhUNb9d...i4bA6' \
-H 'Content-Type: application/json' \
-d '{
      "amount": "1000",
      "currency": "XOF",
      "error_url": "https://example.com/error",
      "success_url": "https://example.com/success"
    }' \
https://api.wave.com/v1/checkout/sessions
<?php

# Specify your API KEY
$api_key = "wave_sn_prod_YhUNb9d...i4bA6";

$checkout_params = [
    "amount" => "1000",
    "currency" => "XOF",
    "error_url" => "https://example.com/error",
    "success_url" => "https://example.com/success",
];

# Define the request options
$curlOptions = [
  CURLOPT_URL => "https://api.wave.com/v1/checkout/sessions",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_TIMEOUT => 5,
  CURLOPT_POST => true,
  CURLOPT_POSTFIELDS => json_encode($checkout_params),
  CURLOPT_HTTPHEADER => [
    "Authorization: Bearer {$api_key}",
    "Content-Type: application/json"
  ],
];

# Execute the request and get a response
$curl = curl_init();
curl_setopt_array($curl, $curlOptions);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
    # You can now decode the response and use the checkout session. Happy coding ;)
    $checkout_session = json_decode($response);

    # You can redirect the user by using the 'wave_launch_url' field.
    $wave_launch_url = $checkout_session["wave_launch_url"]
    header('Location: $wave_launch_url');
    exit;
}
const axios = require('axios');

const api_key = "wave_sn_prod_YhUNb9d...i4bA6";

const checkout_params = {
  amount: "1000",
  currency: "XOF",
  error_url: "https://example.com/error",
  success_url: "https://example.com/success",
};

axios.post('https://api.wave.com/v1/checkout/sessions', checkout_params, {
  headers: {
    'Authorization': `Bearer ${api_key}`,
    'Content-Type': 'application/json',
  },
})
.then((response) => {
  // You can now use the response to redirect the user to the Wave app
  const wave_launch_url = response.data.wave_launch_url;
  window.location.href = wave_launch_url;
})
.catch((error) => {
  console.error(error);
});
import okhttp3.*;
import org.json.JSONObject;

public class CheckoutSession {
  public static void main(String[] args) {
    String api_key = "wave_sn_prod_YhUNb9d...i4bA6";

    OkHttpClient client = new OkHttpClient();
    MediaType mediaType = MediaType.parse("application/json");
    RequestBody body = RequestBody.create(mediaType, new JSONObject() {{
      put("amount", "1000");
      put("currency", "XOF");
      put("error_url", "https://example.com/error");
      put("success_url", "https://example.com/success");
    }}.toString());
    Request request = new Request.Builder()
      .url("https://api.wave.com/v1/checkout/sessions")
      .post(body)
      .addHeader("Authorization", "Bearer " + api_key)
      .addHeader("Content-Type", "application/json")
      .build();

    try {
      Response response = client.newCall(request).execute();
      if (response.isSuccessful()) {
        JSONObject jsonResponse = new JSONObject(response.body().string());
        String wave_launch_url = jsonResponse.getString("wave_launch_url");
        // Redirect the user to the Wave app
        System.out.println(wave_launch_url);
      } else {
        System.out.println("Error: " + response.body().string());
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Creates a Checkout Session object.

Parameters


aggregated_merchant_id string (required for Aggregators)
An aggregated merchant ID to use when making this transaction. This is only available to specific businesses and will return an error if you provide it but don't have permission. If you would like to use this feature, please contact your Wave support representative.

amount string
Total amount to collect from the customer (gross of fees).

client_reference string (optional, up to 255 characters)
A unique string that you provide which can be used to correlate the checkout in your system.

currency string
Three-letter ISO 4217 currency code.

restrict_payer_mobile string (optional)
If you provide this, then the checkout session can only be paid by the Wave account with the specified mobile number. This is a feature that can help you protect your users from scams. Phone numbers follow the E.164 standard. They must include a country code preceded by +. Note: this field was previously called enforce_payer_mobile. This field is also still accepted for compatibility reasons, but the new name is preferred.

error_url string
The URL the customer will be directed to if an error occurs on a payment attempt. You must provide a fully-qualified address using https as the scheme. You may include any information you need in the path itself or in query parameters.

success_url string
The URL the customer will be directed to if the payment succeeds. You must provide a fully-qualified address using https as the scheme. You may include any information you need in the path itself or in query parameters.

Returns


Returns a Checkout Session object.

Retrieve a checkout

GET /v1/checkout/sessions/:id

curl \
-H 'Authorization: Bearer wave_sn_prod_YhUNb9d...i4bA6' \
https://api.wave.com/v1/checkout/sessions/cos-18qq25rgr100a
<?php

# Specify your API KEY
$api_key = "wave_sn_prod_YhUNb9d...i4bA6";

$checkout_id = "cos-18qq25rgr100a";

# Define the request options
$curlOptions = [
  CURLOPT_URL => "https://api.wave.com/v1/checkout/sessions/{$checkout_id}",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_TIMEOUT => 5,
  CURLOPT_HTTPHEADER => [
    "Authorization: Bearer {$api_key}",
  ],
];

# Execute the request and get a response
$curl = curl_init();
curl_setopt_array($curl, $curlOptions);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
    # You can now decode the response and use the checkout session. Happy coding ;)
    $checkout_session = json_decode($response);
    var_dump($checkout_session);
}
const axios = require('axios');

const api_key = "wave_sn_prod_YhUNb9d...i4bA6";
const checkout_id = "cos-18qq25rgr100a";

axios.get('https://api.wave.com/v1/checkout/sessions/' + checkout_id, { headers: { 'Authorization': `Bearer ${api_key}` } })
.then((response) => {
  const checkout_session = response.data;
  console.log(checkout_session);
})
.catch((error) => {
  console.error(error);
});
import okhttp3.*;
import org.json.JSONObject;

public class CheckoutSession {
  public static void main(String[] args) {
    String api_key = "wave_sn_prod_YhUNb9d...i4bA6";
    String checkout_id = "cos-18qq25rgr100a";

    OkHttpClient client = new OkHttpClient();
    Request request = new Request.Builder()
      .url("https://api.wave.com/v1/checkout/sessions/" + checkout_id)
      .get()
      .addHeader("Authorization", "Bearer " + api_key)
      .build();

    try {
      Response response = client.newCall(request).execute();
      if (response.isSuccessful()) {
        JSONObject jsonResponse = new JSONObject(response.body().string());
        System.out.println(jsonResponse.toString());
      } else {
        System.out.println("Error: " + response.body().string());
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Retrieves a Checkout Session object.

Parameters


No parameters.

Returns


Returns a Checkout Session object if a valid identifier was provided. Returns an checkout session error otherwise.

Retrieve a checkout by Transaction ID

GET /v1/checkout/sessions

curl -X GET \
  --url https://api.wave.com/v1/checkout/sessions?transaction_id=FAH.4827.1734 \
  -H 'Authorization : Bearer wave_sn_prod_YhUNb9d...i4bA6'
<?php

# Specify your API KEY
$api_key = "wave_sn_prod_YhUNb9d...i4bA6";

$transaction_id = "FAH.4827.1734";

# Define the request options
$curlOptions = [
  CURLOPT_URL => "https://api.wave.com/v1/checkout/sessions?transaction_id={$transaction_id}",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_TIMEOUT => 5,
  CURLOPT_HTTPHEADER => [
    "Authorization: Bearer {$api_key}",
  ],
];

# Execute the request and get a response
$curl = curl_init();
curl_setopt_array($curl, $curlOptions);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
    # You can now decode the response and use the checkout session. Happy coding ;)
    $checkout_session = json_decode($response);
    var_dump($checkout_session);
}
const axios = require('axios');

const api_key = "wave_sn_prod_YhUNb9d...i4bA6";
const transaction_id = "FAH.4827.1734";

axios.get('https://api.wave.com/v1/checkout/sessions', { params: { transaction_id }, headers: { 'Authorization': `Bearer ${api_key}` } })
.then((response) => {
  const checkout_session = response.data;
  console.log(checkout_session);
})
.catch((error) => {
  console.error(error);
});
import okhttp3.*;
import org.json.JSONObject;

public class CheckoutSession {
  public static void main(String[] args) {
    String api_key = "wave_sn_prod_YhUNb9d...i4bA6";
    String transaction_id = "FAH.4827.1734";

    OkHttpClient client = new OkHttpClient();
    Request request = new Request.Builder()
      .url("https://api.wave.com/v1/checkout/sessions?transaction_id=" + transaction_id)
      .get()
      .addHeader("Authorization", "Bearer " + api_key)
      .build();

    try {
      Response response = client.newCall(request).execute();
      if (response.isSuccessful()) {
        JSONObject jsonResponse = new JSONObject(response.body().string());
        System.out.println(jsonResponse.toString());
      } else {
        System.out.println("Error: " + response.body().string());
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Parameters


Key Type Description
transaction_id string The transaction ID of the checkout session to retrieve.

Returns


Returns a Checkout Session object if a valid identifier was provided. Returns an checkout session error otherwise.

Search for checkouts

Retrieves a list of Checkout Session objects that match the search criteria.

GET /v1/checkout/sessions/search

curl -X GET \
  --url https://api.wave.com/v1/checkout/sessions/search?client_reference=123456 \
  -H 'Authorization : Bearer wave_sn_prod_YhUNb9d...i4bA6'
<?php

# Specify your API KEY
$api_key = "wave_sn_prod_YhUNb9d...i4bA6";

$client_reference = "123456";

# Define the request options
$curlOptions = [
  CURLOPT_URL => "https://api.wave.com/v1/checkout/sessions/search?client_reference={$client_reference}",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_TIMEOUT => 5,
  CURLOPT_HTTPHEADER => [
    "Authorization : Bearer {$api_key}",
  ],
];

# Execute the request and get a response
$curl = curl_init();
curl_setopt_array($curl, $curlOptions);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
    # You can now decode the response and use the checkout session. Happy coding ;)
    $checkout_session = json_decode($response);
    var_dump($checkout_session);
}
const axios = require('axios');

const api_key = "wave_sn_prod_YhUNb9d...i4bA6";
const client_reference = "123456";

axios.get('https://api.wave.com/v1/checkout/sessions/search', { params: { client_reference }, headers: { 'Authorization': `Bearer ${api_key}` } })
.then((response) => {
  const checkout_session = response.data;
  console.log(checkout_session);
})
.catch((error) => {
  console.error(error);
});
import okhttp3.*;
import org.json.JSONObject;

public class CheckoutSession {
  public static void main(String[] args) {
    String api_key = "wave_sn_prod_YhUNb9d...i4bA6";
    String client_reference = "123456";

    OkHttpClient client = new OkHttpClient();
    Request request = new Request.Builder()
      .url("https://api.wave.com/v1/checkout/sessions/search?client_reference=" + client_reference)
      .get()
      .addHeader("Authorization", "Bearer " + api_key)
      .build();

    try {
      Response response = client.newCall(request).execute();
      if (response.isSuccessful()) {
        JSONObject jsonResponse = new JSONObject(response.body().string());
        System.out.println(jsonResponse.toString());
      } else {
        System.out.println("Error: " + response.body().string());
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Example response

{
  "result": [
    {
      "id": "cos-18qq25rgr100a",
      "amount": "1000",
      "checkout_status": "complete",
      "client_reference": "123456",
      "currency": "XOF",
      "error_url": "https://example.com/error",
      "last_payment_error": null,
      "business_name": "Papa's Penguins",
      "payment_status": "succeeded",
      "transaction_id": "TDH5TEWTLFE",
      "aggregated_merchant_id": "am-7lks22ap113t4",
      "success_url": "https://example.com/success",
      "wave_launch_url": "https://pay.wave.com/c/cos-18qq25rgr100a",
      "when_completed": "2021-12-08T10:15:32Z",
      "when_created": "2021-12-08T10:13:04Z",
      "when_expires": "2021-12-09T10:13:04Z"
    }
  ]
}

Parameters


Key Type Description
client_reference string A unique string that you provide which can be used to correlate the checkout in your system.

Return attributes

Key Type Description
result List of checkout sessions The list of payouts that match the search criteria.

Refund a checkout

POST /v1/checkout/sessions/:id/refund

curl -X POST \
-H 'Authorization: Bearer wave_sn_prod_YhUNb9d...i4bA6' \
https://api.wave.com/v1/checkout/sessions/cos-18qq25rgr100a/refund
<?php

# Specify your API KEY
$api_key = "wave_sn_prod_YhUNb9d...i4bA6";

$checkout_id = "cos-18qq25rgr100a";

# Define the request options
$curlOptions = [
  CURLOPT_URL => "https://api.wave.com/v1/checkout/sessions/{$checkout_id}/refund",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_TIMEOUT => 5,
  CURLOPT_POST => true,
  CURLOPT_HTTPHEADER => [
    "Authorization: Bearer {$api_key}",
  ],
];

# Execute the request and get a response
$curl = curl_init();
curl_setopt_array($curl, $curlOptions);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
    # You can now decode the response and use the checkout session. Happy coding ;)
    $checkout_session = json_decode($response);
    var_dump($checkout_session);
}
const axios = require('axios');

const api_key = "wave_sn_prod_YhUNb9d...i4bA6";
const checkout_id = "cos-18qq25rgr100a";

axios.post('https://api.wave.com/v1/checkout/sessions/' + checkout_id + '/refund', null, { headers: { 'Authorization': `Bearer ${api_key}` } })
.then((response) => {
  const checkout_session = response.data;
  console.log(checkout_session);
})
.catch((error) => {
  console.error(error);
});
import okhttp3.*;
import org.json.JSONObject;

public class CheckoutSession {
  public static void main(String[] args) {
    String api_key = "wave_sn_prod_YhUNb9d...i4bA6";
    String checkout_id = "cos-18qq25rgr100a";

    OkHttpClient client = new OkHttpClient();
    Request request = new Request.Builder()
      .url("https://api.wave.com/v1/checkout/sessions/" + checkout_id + "/refund")
      .post(RequestBody.create(null, new byte[0]))
      .addHeader("Authorization", "Bearer " + api_key)
      .build();

    try {
      Response response = client.newCall(request).execute();
      if (response.isSuccessful()) {
        JSONObject jsonResponse = new JSONObject(response.body().string());
        System.out.println(jsonResponse.toString());
      } else {
        System.out.println("Error: " + response.body().string());
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Refunds the user payment associated with a Checkout Session.

Parameters


No parameters.

Returns


Returns an empty body and an HTTP 200 Success code when the payment is refunded, and an error otherwise. If the Checkout Session doesn't exists this returns an HTTP 404 Not Found error.

If you try to refund a checkout twice, no additional transaction will be created, but this endpoint will simply return HTTP 200 Success again.

All normal transaction restrictions apply: if the recipient has reached their monthly limit or their account is for any reason blocked then the corresponding error is returned as well.

Expire a checkout

POST /v1/checkout/sessions/:id/expire

curl -X POST \
-H 'Authorization: Bearer wave_sn_prod_YhUNb9d...i4bA6' \
https://api.wave.com/v1/checkout/sessions/cos-18qq25rgr100a/expire
<?php

# Specify your API KEY
$api_key = "wave_sn_prod_YhUNb9d...i4bA6";

$checkout_id = "cos-18qq25rgr100a";

# Define the request options
$curlOptions = [
  CURLOPT_URL => "https://api.wave.com/v1/checkout/sessions/{$checkout_id}/expire",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_TIMEOUT => 5,
  CURLOPT_POST => true,
  CURLOPT_HTTPHEADER => [
    "Authorization: Bearer {$api_key}",
  ],
];

# Execute the request and get a response
$curl = curl_init();
curl_setopt_array($curl, $curlOptions);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
    # You can now decode the response and use the checkout session. Happy coding ;)
    $checkout_session = json_decode($response);
    var_dump($checkout_session);
}
const axios = require('axios');

const api_key = "wave_sn_prod_YhUNb9d...i4bA6";
const checkout_id = "cos-18qq25rgr100a";

axios.post('https://api.wave.com/v1/checkout/sessions/' + checkout_id + '/expire', null, { headers: { 'Authorization': `Bearer ${api_key}` } })
.then((response) => {
  const checkout_session = response.data;
  console.log(checkout_session);
})
.catch((error) => {
  console.error(error);
});
import okhttp3.*;
import org.json.JSONObject;

public class CheckoutSession {
  public static void main(String[] args) {
    String api_key = "wave_sn_prod_YhUNb9d...i4bA6";
    String checkout_id = "cos-18qq25rgr100a";

    OkHttpClient client = new OkHttpClient();
    Request request = new Request.Builder()
      .url("https://api.wave.com/v1/checkout/sessions/" + checkout_id + "/expire")
      .post(RequestBody.create(null, new byte[0]))
      .addHeader("Authorization", "Bearer " + api_key)
      .build();

    try {
      Response response = client.newCall(request).execute();
      if (response.isSuccessful()) {
        JSONObject jsonResponse = new JSONObject(response.body().string());
        System.out.println(jsonResponse.toString());
      } else {
        System.out.println("Error: " + response.body().string());
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Expires an open Checkout Session, preventing it from being completed by any user.

Parameters


No parameters.

Returns


Returns an empty body and an HTTP 200 Success code when successfully expiring the session. Can also return the following errors:

Checkout API errors

A couple of things can go wrong when attempting to create a checkout session, or when a user tries to pay an existing session. The following is the list of errors that can occur when using this API.

This is in addition to the general HTTP code that can be returned as described in the errors section.

Checkout Session errors

error_code explanation
authorization-error The API key is either missing or incomplete. Make sure you copy-pasted the entire key and refer to the authentication section for instructions.
missing-auth-header The request is missing a Bearer token in the Authorization header. See Authentication for instructions.
checkout-refund-failed You tried to refund a checkout but the transaction couldn't be made. It's possible that the payment wasn't in a success state beforehand, the recipient account was blocked, or your wallet didn't have sufficient funds for the transaction.
checkout-session-not-found You requested a checkout session by ID that we can't match to anything in our system. You should double-check that the ID corresponds to one that you've received in a response.
internal-server-error A technical error has occurred in Wave's system. We work very hard to avoid this, so it is only reserved for unexpected cases.
request-validation-error Your request doesn't match the object type required. These are things like a missing field or an invalid type in a provided field like an invalid phone number. The error_message will help you with details.
service-unavailable In some rare and short cases Wave services are down for maintenance. You can try the request again later.
unauthorized-wallet The account you are using is not authorized to use this API. Please get in touch with a Wave partner representative to discuss getting access.

Payment errors

These errors will be delivered as part of the webhook that notifies your system of a failed checkout payment attempt. They basically answer why the payment of the user failed. The code will be under the last_payment_error field of the webhook body.

error_code explanation
blocked-account The customer used a blocked account to try and pay for the checkout.
cross-border-payment-not-allowed Sending a payment between countries is often restricted for regulatory reasons.
customer-age-restricted The customer is underage (or of unknown age), but is trying to pay for an age restricted product or service.
insufficient-funds The user didn't have enough account balance.
kyb-limits-exceeded Your business has exceeded its account limits. Please contact Wave to find out how you can increase your limits.
payer-mobile-mismatch If you passed the restrict_payer_mobile (formerly enforce_payer_mobile) parameter, then the checkout session can only be paid by the number you specified. This error is returned if a customer with a different number tried to pay.
payment-failure A technical error has occurred in Wave's system. We work very hard to avoid this, so it error code only reserved for unexpected cases.

Changelog

2024-03-29

Removes override_business_name details from the Checkout API

2022-10-17

Added aggregated_merchant_id details to the Checkout API.

2022-05-10

The Checkout API now validates decimal places following the rules described in the Amount section.

2022-03-29

Adds override_business_name details to Checkout API

2022-03-23

Initial release of Checkout and Balance APIs.