API Reference

Transactions are the main way to transfer funds between merchants and customers. The following types of transactions are supported:

Cashin (Deposit)

Request that funds be deposited into your merchant account.

Path

${BASE_URL}/transactions/cashin

Request Headers

FieldTypeDescription
Acceptstringapplication/json
Content-Typestringapplication/json
Idempotency-KeystringOptional Unique String with maxLength of 32 for each request
AuthorizationstringBearer <access_token>
X-Webhook-ModestringSpecify your current environment associated with the webhook.

Body

FieldTypeDescription
amountnumberThe amount to be deposited.
numberstringThe phone number of the customer.

Example

cURL
curl --location --request POST \
  'https://payments.paypack.rw/api/transactions/cashin' \
  --header 'Content-Type: application/json' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer {access_token}' \
  --data-raw '{ "amount": 100, "number": "078xxxxxxx"}'
Go
package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
    "strings"
)

func main() {

    url := "https://payments.paypack.rw/api/transactions/cashin"
    method := "POST"

    payload := strings.NewReader(`{
  "amount": 1000,
  "number": "078xxxxxxx"
}`)

    client := &http.Client{}
    req, err := http.NewRequest(method, url, payload)

    if err != nil {
        fmt.Println(err)
        return
    }
    req.Header.Add("Content-Type", "application/json")
    req.Header.Add("Accept", "application/json")
    req.Header.Add("Authorization", "Bearer {access_token}")

    res, err := client.Do(req)
    if err != nil {
        fmt.Println(err)
        return
    }
    defer res.Body.Close()

    body, err := ioutil.ReadAll(res.Body)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(string(body))
}
JavaScript
var request = require("request");
var options = {
  method: "POST",
  url: "https://payments.paypack.rw/api/transactions/cashin",
  headers: {
    "Content-Type": "application/json",
    Accept: "application/json",
    Authorization: "Bearer {access_token}",
  },
  body: JSON.stringify({
    amount: 1000,
    number: "078xxxxxxx",
  }),
};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});
PHP
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://payments.paypack.rw/api/transactions/cashin',
  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 =>'{
    "amount":xxx,
    "number":"07xxxxxxx"
}',
  CURLOPT_HTTPHEADER => array(
    'Authorization: Bearer {token}',
    'Content-Type: application/json'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
Python
import requests
import json

url = "https://payments.paypack.rw/api/transactions/cashin"

payload = json.dumps({
  "amount": 1000,
  "number": "078xxxxxxx"
})
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer {access_token}'
}

response = requests.request("POST", url, headers=headers, data=payload)

print(response.text)

Response

{
  "amount": 1000,
  "created_at": "2005-11-09T21:19:07.459Z",
  "kind": "CASHIN",
  "ref": "d0bb2807-1d52-4795-b373-3feaf63dceb1",
  "status": "pending"
}

Cashout (Withdraw)

Request that money be withdrawn from your merchant account.

Path

/transactions/cashout

Request Headers

FieldTypeDescription
Acceptstringapplication/json
Content-Typestringapplication/json
Idempotency-KeystringOptional Unique String with maxLength of 32 for each request
AuthorizationstringBearer <access_token>
X-Webhook-ModestringSpecify your current environment associated with the webhook.

Body

FieldTypeDescription
amountnumberThe amount to be withdrawn.
numberstringThe phone number of the customer.

Example

cURL
curl --location --request POST \
  'https://payments.paypack.rw/api/transactions/cashout' \
  --header 'Content-Type: application/json' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer {access_token}' \
  --data-raw '{ "amount": 1000, "number": "078xxxxxxx" }'
Go
package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
    "strings"
)

func main() {

    url := "https://payments.paypack.rw/api/transactions/cashout"
    method := "POST"

    payload := strings.NewReader(`{
    "amount": 1000,
    "number": "078xxxxxxx",
    }`)

    client := &http.Client{}
    req, err := http.NewRequest(method, url, payload)

    if err != nil {
        fmt.Println(err)
        return
    }
    req.Header.Add("Content-Type", "application/json")
    req.Header.Add("Accept", "application/json")
    req.Header.Add("Authorization", "Bearer {access_token}")

    res, err := client.Do(req)
    if err != nil {
        fmt.Println(err)
        return
    }
    defer res.Body.Close()

    body, err := ioutil.ReadAll(res.Body)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(string(body))
}
JavaScript
var request = require("request");
var options = {
  method: "POST",
  url: "https://payments.paypack.rw/api/transactions/cashout",
  headers: {
    "Content-Type": "application/json",
    Accept: "application/json",
    Authorization: "Bearer {access_token}",
  },
  body: JSON.stringify({
    amount: 1000,
    number: "078xxxxxxx",
  }),
};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});
PHP
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://payments.paypack.rw/api/transactions/cashout',
  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 =>'{
    "amount":1000,
    "number":"07xxxxxxx"
}',
  CURLOPT_HTTPHEADER => array(
    'Authorization: Bearer {token}',
    'Content-Type: application/json'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
Python
import requests
import json

url = "https://payments.paypack.rw/api/transactions/cashout"

payload = json.dumps({
  "amount": 1000,
  "number": "078xxxxxxx"
})
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer {access_token}'
}

response = requests.request("POST", url, headers=headers, data=payload)

print(response.text)

Response

{
  "amount": 1000,
  "created_at": "2005-11-09T21:19:07.459Z",
  "kind": "CASHOUT",
  "ref": "d0bb2807-1d52-4795-b373-3feaf63dceb1",
  "status": "pending"
}
Both Cashin and Cashout support idempotency-key as an optional header with unique string of 32 char length, which means that if you didn't set the header, we will generate a unique string for you.

Finding a Transaction

Transactions are identified by their unique reference key, which is generated during its creation.

Path

/transactions/find/{ref}

Request Headers

FieldTypeDescription
Acceptstringapplication/json
Content-Typestringapplication/json
AuthorizationstringBearer <access_token>

Query Parameters

FieldTypeDescription
refstringThe unique reference key of the transaction.

Example

cURL
curl --location --request GET \
  'https://payments.paypack.rw/api/transactions/find/{ref}' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer {access_token}'
Go
package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
)

func main() {

    url := "https://payments.paypack.rw/api/transactions/find/{referenceKey}"
    method := "GET"

    client := &http.Client{}
    req, err := http.NewRequest(method, url, nil)

    if err != nil {
        fmt.Println(err)
        return
    }
    res, err := client.Do(req)
    if err != nil {
        fmt.Println(err)
        return
    }
    defer res.Body.Close()

    body, err := ioutil.ReadAll(res.Body)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(string(body))
}
JavaScript
var request = require('request');

var options = {
  'method': 'GET',
  'url': 'https://payments.paypack.rw/api/transactions/find/{referenceKey}',
  'headers': {'Authorization': 'Bearer {access_token}'}
};

request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});
PHP
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
CURLOPT_URL => 'https://payments.paypack.rw/api/transactions/find/{reference_key}',
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 => array(
'Authorization: Bearer {token}'
),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
Python
import requests

url = "https://payments.paypack.rw/api/transactions/find/{referenceKey}"

payload={}
headers = {'Authorization': 'Bearer {access_token}'}

response = requests.request("GET", url, headers=headers, data=payload)

print(response.text)

Response

{
  "amount": 1000,
  "client": "078xxxxxxx",
  "fee": 23,
  "kind": "CASHOUT",
  "merchant": "IJOK9F",
  "ref": "d0bb2807-1d52-4795-b373-3feaf63dceb1",
  "status": "pending",
  "timestamp": "2014-05-16T08:28:06.801064-04:00"
}

What is Idempotency-key?

  • Idempotency key is a unique identifier that can be used to ensure that a certain request can only be executed once. This is particularly useful when dealing with financial transactions, where it is important to avoid duplicate charges or refunds.
  • In the case of Paypack-Payments, an idempotency key can be used to prevent multiple payments from being made for the same request. For example, if you attempts to cashin/cashout twice due to a network error or other issue, the second attempt will be rejected by the Paypack-Payments API and you will not be charged twice.
  • We recommends using a unique and randomly generated idempotency key for each request made to the API. This ensures that even if there are multiple requests with the same idempotency key, only the first request will be executed, avoiding any accidental duplicate charges or other issues.