Créer un transfert interwallet
curl --request POST \
--url https://api.saspay.me/api/v1/wallet-transfers/ \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: <idempotency-key>' \
--data '
{
"from_country": "BJ",
"to_country": "CM",
"from_amount": "100000.00"
}
'import requests
url = "https://api.saspay.me/api/v1/wallet-transfers/"
payload = {
"from_country": "BJ",
"to_country": "CM",
"from_amount": "100000.00"
}
headers = {
"Idempotency-Key": "<idempotency-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'Idempotency-Key': '<idempotency-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({from_country: 'BJ', to_country: 'CM', from_amount: '100000.00'})
};
fetch('https://api.saspay.me/api/v1/wallet-transfers/', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.saspay.me/api/v1/wallet-transfers/",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'from_country' => 'BJ',
'to_country' => 'CM',
'from_amount' => '100000.00'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"Idempotency-Key: <idempotency-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.saspay.me/api/v1/wallet-transfers/"
payload := strings.NewReader("{\n \"from_country\": \"BJ\",\n \"to_country\": \"CM\",\n \"from_amount\": \"100000.00\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Idempotency-Key", "<idempotency-key>")
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.saspay.me/api/v1/wallet-transfers/")
.header("Idempotency-Key", "<idempotency-key>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"from_country\": \"BJ\",\n \"to_country\": \"CM\",\n \"from_amount\": \"100000.00\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.saspay.me/api/v1/wallet-transfers/")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Idempotency-Key"] = '<idempotency-key>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"from_country\": \"BJ\",\n \"to_country\": \"CM\",\n \"from_amount\": \"100000.00\"\n}"
response = http.request(request)
puts response.read_body{
"id": "1a2b3c4d-1111-2222-3333-444455556666",
"reference": "f4e5d6c7-3333-4444-5555-666677778888",
"merchant": "8a1f5c3e-0000-1111-2222-333344445555",
"requested_by_member": null,
"from_country": "BJ",
"to_country": "CM",
"from_amount": "100000.00",
"from_currency": "XOF",
"to_amount": "984.00",
"to_currency": "XAF",
"exchange_rate": "0.00984000",
"status": "PENDING",
"approved_by_admin": null,
"approved_at": null,
"completed_at": null,
"rejection_reason": null,
"created_at": "2026-08-12T10:10:00Z",
"updated_at": "2026-08-12T10:10:00Z"
}{
"message": "Un transfert interwallet est déjà en attente pour ce marchand — attendez sa résolution avant d'en demander un autre.",
"code": "transfer_already_pending"
}Wallet
Créer un transfert interwallet
Déplace des fonds entre deux de vos wallets (pays différents), avec conversion automatique
POST
/
wallet-transfers
/
Créer un transfert interwallet
curl --request POST \
--url https://api.saspay.me/api/v1/wallet-transfers/ \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: <idempotency-key>' \
--data '
{
"from_country": "BJ",
"to_country": "CM",
"from_amount": "100000.00"
}
'import requests
url = "https://api.saspay.me/api/v1/wallet-transfers/"
payload = {
"from_country": "BJ",
"to_country": "CM",
"from_amount": "100000.00"
}
headers = {
"Idempotency-Key": "<idempotency-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'Idempotency-Key': '<idempotency-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({from_country: 'BJ', to_country: 'CM', from_amount: '100000.00'})
};
fetch('https://api.saspay.me/api/v1/wallet-transfers/', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.saspay.me/api/v1/wallet-transfers/",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'from_country' => 'BJ',
'to_country' => 'CM',
'from_amount' => '100000.00'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"Idempotency-Key: <idempotency-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.saspay.me/api/v1/wallet-transfers/"
payload := strings.NewReader("{\n \"from_country\": \"BJ\",\n \"to_country\": \"CM\",\n \"from_amount\": \"100000.00\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Idempotency-Key", "<idempotency-key>")
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.saspay.me/api/v1/wallet-transfers/")
.header("Idempotency-Key", "<idempotency-key>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"from_country\": \"BJ\",\n \"to_country\": \"CM\",\n \"from_amount\": \"100000.00\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.saspay.me/api/v1/wallet-transfers/")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Idempotency-Key"] = '<idempotency-key>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"from_country\": \"BJ\",\n \"to_country\": \"CM\",\n \"from_amount\": \"100000.00\"\n}"
response = http.request(request)
puts response.read_body{
"id": "1a2b3c4d-1111-2222-3333-444455556666",
"reference": "f4e5d6c7-3333-4444-5555-666677778888",
"merchant": "8a1f5c3e-0000-1111-2222-333344445555",
"requested_by_member": null,
"from_country": "BJ",
"to_country": "CM",
"from_amount": "100000.00",
"from_currency": "XOF",
"to_amount": "984.00",
"to_currency": "XAF",
"exchange_rate": "0.00984000",
"status": "PENDING",
"approved_by_admin": null,
"approved_at": null,
"completed_at": null,
"rejection_reason": null,
"created_at": "2026-08-12T10:10:00Z",
"updated_at": "2026-08-12T10:10:00Z"
}{
"message": "Un transfert interwallet est déjà en attente pour ce marchand — attendez sa résolution avant d'en demander un autre.",
"code": "transfer_already_pending"
}Le header
Idempotency-Key est requis — un double-clic/retry réseau sans elle réserverait deux fois le montant sur le wallet source.Un seul transfert
PENDING est autorisé à la fois par marchand. Le wallet source doit ne pas être gelé (le wallet destination, lui, reste toujours créditable même gelé). Selon votre configuration, la réponse peut revenir directement en COMPLETED (auto-approbation activée par un administrateur) ou rester PENDING jusqu’à validation. Erreurs possibles, toutes en 422 : same_country, transfer_already_pending, wallet_frozen, insufficient_balance, no_exchange_rate.Authorizations
Clé API secrète du marchand — header Authorization: Bearer sk_live_xxx (ou sk_test_xxx en environnement de test).
Headers
Valeur unique par tentative logique de transfert.
Body
application/json
Response
Transfert créé (PENDING ou COMPLETED si auto-approuvé)
⌘I