Direct Integration

POST/api/v1/pocket/transfer/initiate

If you have your own checkout or interface and want to do direct API integration, you can call the endpoint below to initiate a transfer request to the Pocket user. This does not require the SDK.

Request Parameters

NameTypeRequiredDescription
tagstringYesPocket user's tag.
amountintegerYesAmount in kobo.
narrationstringYesDescription of the payment request.
referencestringYesYour unique reference.
product_namestringNoYour application name or the name of what the user is paying for.
wallet_idstringNoMust be an Expense wallet. If you have a particular business wallet you want payments settled to, pass its ID (from dashboard). If omitted, the primary expense wallet is used.
metaobjectNoCustom data. You will receive it back in stringified format via webhooks.
1
cURL Example
(cURL)
curl -X POST "https://api.piggyvest.business/api/v1/pocket/transfer/initiate" \
-H "Authorization: Bearer YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"tag": "mezigaboshi",
"amount": 500000,
"narration": "subscription Fee",
"reference": "your-unique-reference",
"product_name": "my-app",
"wallet_id": "6d086bce-58ea-46d0-b77e-e1c398d6de4d"
}'
2
Node.js Example
(JavaScript)
import axios from 'axios'
const secretKey = process.env.PVB_SECRET_KEY
const url = `${process.env.PVB_BASE_URL}/api/v1/pocket/transfer/initiate`
const payload = {
tag: "mazigraphql",
amount: 500000,
narration: "Pay with pocket test",
reference: "your-unique-reference",
product_name: "my-app",
wallet_id: "0b86bccc-5d6a-45a9-b27c-a2e86864e84d",
meta: {} // Anything you want to get back via webhooks
}
await axios.post(url, payload, {
headers: {
'Authorization': `Bearer ${secretKey}`,
},
})
Sandbox Note: In sandbox mode you cannot go to the Pocket app to accept or reject a payment after calling this endpoint. We internally simulate the success case. If you want to simulate an instance where the user rejects the request, add the key "simulate_for": "failure" to the request body to receive a failed webhook.

Webhook Structure

After the Pocket user responds to the payment request, a webhook will be sent to your configured webhook URL.

Success Webhook

When the Pocket user accepts the payment, they will be debited and your destination account will be credited. A webhook with the following structure is sent:

pocket-transfer.inflow.success
(JSON)
{
"eventId": "01JBXTNTHH9Y5NY01TVX6AJSQJ",
"customer_id": "55b71d43-2efa-4ad8-ab67-2addabaee1ad",
"eventType": "pocket-transfer.inflow.success",
"eventCategory": "inflow_transaction",
"eventData": {
"id": "183d87ab-5714-4c3b-b71e-81fb93f0c4c3",
"customer_id": "55b71d43-2efa-4ad8-ab67-2addabaee1ad",
"destination_wallet_id": "5fa805a5-f228-4cac-8d9f-b9b9c20e3fdd",
"type": "inter",
"category": "pocket_inflow",
"amount": 32000,
"currency": "NGN",
"narration": "Sent by mazigraphql",
"transaction_id": "b2ddaea4-2692-4394-af43-d0f6e882a6b4",
"timestamp": "2024-11-05T09:32:14.162Z",
"internal_reference": "01JBXTNS79TAQT3W0D09D148C0",
"status": "COMPLETED",
"provider": "pocket",
"third_party_reference": "pvfb_6c885641-b4e6-4431-a680-65fcefb223631730799101384",
"fee": 1.50,
"destination_wallet_balance": "741015",
"destination_wallet_ledger_balance": "741015"
},
"pvb_reference": "pvfb_6c885641-b4e6-4431-a680-65fcefb223631730799101384",
"pvb_wallet": "f335f21e-6e8e-43d5-8211-b7aa08a5fba5",
"pvb_destination_wallet": null,
"pvb_third_party_reference": "your-reference-when-instantiating-transfer",
"pvb_schedule_payment_id": null,
"pvb_meta": {}
}

Failure Webhook

If the Pocket user rejects the request, the following webhook is sent:

pocket-transfer.inflow.failed
(JSON)
{
"eventId": "01JB4WA9AJ457T4QT0VPCNXJQ5",
"customer_id": "c096507d-dc32-45d2-9c01-871a27abfd10",
"eventType": "pocket-transfer.inflow.failed",
"eventCategory": "inflow_transaction",
"eventData": {
"destination_wallet": "df5ec9e3-efa9-459c-b0b6-d88f9288b0ba",
"customer_id": "c096507d-dc32-45d2-9c01-871a27abfd10",
"amount": 400000,
"currency": "NGN",
"type": "inter",
"category": "pocket_inflow",
"status": "failed",
"service_type": "INSTANT_TRANSFER",
"initiator_reference": "pvfb_e0dc922d-4901-4708-acc8-fb156c0dce3c1729961447464",
"narration": "Pay with pocket"
},
"pvb_reference": "pvfb_e0dc922d-4901-4708-acc8-fb156c0dce3c1729961447464",
"pvb_wallet": "f335f21e-6e8e-43d5-8211-b7aa08a5fba5",
"pvb_destination_wallet": null,
"pvb_third_party_reference": "your-reference-when-instantiating-transfer",
"pvb_schedule_payment_id": null,
"pvb_meta": {}
}

Webhook Signature Validation

To validate that a webhook payload came from us, we send an x-pvb-signature in the request headers. Below is a sample Node.js Express snippet to validate the signature using HMAC SHA-512:

Signature Validation (Node.js)
(JavaScript)
import crypto from 'crypto'
const secretKey = process.env.PVB_SECRET_KEY
router.post('/my-webhook-url', function (request, response) {
const hash = crypto
.createHmac('sha512', secretKey)
.update(JSON.stringify(request.body))
.digest('hex')
if (hash !== request.headers['x-pvb-signature']) {
// Invalid signature — return early
return response.sendStatus(200);
}
// Validated — process the webhook
response.sendStatus(200);
})