Learn how to accept payments, manage transactions, and handle callbacks with YaYa Wallet's payment integration
Welcome to the YaYa Wallet Payment Integration documentation. This guide will help you integrate our payment processing system into your application. Our API is RESTful and uses JSON for request and response bodies.
The YaYa Wallet Payment Integration consists of several key components and follows this payment flow:
Key features of the system:
POST /api/auth/token
Obtain an access token for API authentication.
Request: { "client_id": "your_client_id", "client_secret": "your_client_secret", "grant_type": "client_credentials" } Response: { "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "token_type": "Bearer", "expires_in": 3600, "scope": "user" }
Include the access token in the Authorization header for all authenticated requests:
Authorization: Bearer your_access_token
POST /api/payment-intent
Creates a new payment intent. Requires OAuth2 authentication.
Request: { "bankBic": "YAYAETAA", "bankAccount": "antenehgebey", "amount": 1000, "paymentReference": "INV-005", "description": "June bill", "feeOnMerchant": true, "returnUrl": "https://yourwebsite.com/thank-you", "callbackUrl": "https://6833e09e464b499636008b3e.mockapi.io/callback" } Response: { "success": true, "data": { "id": "0ec6005f-820c-4ab4-84aa-2311fb8262f7", "urlSlug": "92AE1D227EE1", "paymentCode": "92AE1D227EE1", "paymentReference": "INV-0895", "amount": 1000, "currency": "ETB", "processingFee": 20, "total": 1020, "bankBic": "YAYAETAA", "bankAccount": "antenehgebey", "feeOnMerchant": true, "status": "pending", "qrCode": "00020101021228630032ee5b47b18b3544a0960673b04df2c0b70108YAYAETAA0211911655619_s52045411530323054071000.005802ET5926SUNRISE FOOD COMPLEX P L C6011Addis Abeba62430108INV-08950211911655619_s0612yayacheckout6304B01D", "description": "June bill", "cardPaymentUrl": null, "paymentLink": "http://localhost:8080/p/92AE1D227EE1", "thankYouUrl": "https://env-url/ty/92AE1D227EE1", "returnUrl": "https://yourwebsite.com/thank-you", "callbackUrl": "https://6833e09e464b499636008b3e.mockapi.io/callback", "createdAt": "2025-06-01T09:27:32.070Z", "updatedAt": "2025-06-01T09:27:32.070Z" } }
After creating a payment intent, you must share the paymentLink
with the payer to receive payment. You can either:
The payment link is the primary way for payers to complete their payment. Without sharing this link, the payer won't be able to make the payment.
Alternative Payment Method: You may also share the payment code with the payer, who can then make a direct bank transfer to YaYa Wallet account 7777. The payer must include the payment code in the transfer reason/message field for proper payment matching.
GET /api/payment-intents
Retrieves paginated list of payment intents for the authenticated merchant. Requires OAuth2 authentication.
Headers: Authorization: Bearer your_access_token Query Parameters: - page: Page number (default: 1) - limit: Items per page (default: 10) - status: Filter by status (pending, paid, failed) - startDate: Filter by start date (YYYY-MM-DD) - endDate: Filter by end date (YYYY-MM-DD) - sortBy: Sort field (created_at, updated_at, amount, status) - sortOrder: Sort order (asc, desc) Response: { "draw": 1, "recordsTotal": 100, "recordsFiltered": 100, "data": [ { "id": "uuid", "amount": 1000.00, "processingFee": 25.00, "total": 1025.00, "status": "paid", "merchantName": "Example Store", "paymentReference": "INV-001", "transactionReference": "TRX123456", "urlSlug": "example-store", "createdAt": "2024-03-20T10:00:00Z", "updatedAt": "2024-03-20T10:05:00Z", "paymentLink": "https://env-url/p/example-store", "thankYouUrl": "https://env-url/ty/example-store", "localization": { "formattedAmount": "ETB 1,000.00", "formattedProcessingFee": "ETB 25.00", "formattedTotal": "ETB 1,025.00", "createdAt": "Mar 20, 2024 10:00 AM", "updatedAt": "Mar 20, 2024 10:05 AM" }, "urlSlug": "example-store" } ] }
GET /api/payment-info/:urlSlug
Retrieves detailed information about a specific payment intent using the URL slug. Requires OAuth2 authentication.
Headers: Authorization: Bearer your_access_token Response: { "id": "uuid", "amount": 1000.00, "processingFee": 25.00, "total": 1025.00, "status": "paid", "merchantName": "Example Store", "paymentReference": "INV-001", "transactionReference": "TRX123456", "urlSlug": "example-store", "createdAt": "2024-03-20T10:00:00Z", "updatedAt": "2024-03-20T10:05:00Z", "paymentLink": "https://env-url/p/example-store", "thankYouUrl": "https://env-url/ty/example-store", "localization": { "formattedAmount": "ETB 1,000.00", "formattedProcessingFee": "ETB 25.00", "formattedTotal": "ETB 1,025.00", "createdAt": "Mar 20, 2024 10:00 AM", "updatedAt": "Mar 20, 2024 10:05 AM" }, "beneficiaryAccountDetails": { "bankBic": "YAYAETAA", "bankAccount": "1234567890", "accountHolderName": "Example Store" } }
DELETE /api/payment-intent/:paymentId/cancel
Cancels a pending payment intent by payment ID. Requires OAuth2 authentication.
Headers: Authorization: Bearer your_access_token Response: { "success": true, "message": "Payment intent cancelled successfully", "data": { "paymentIntentId": "uuid", "paymentId": "uuid", "uniqueRef": "string" } }
GET /api/payment-intent/generate-reference
Generates a unique merchant reference for new transactions. Requires OAuth2 authentication.
Response: { "reference": "INV-123456" }
GET /api/banks
Retrieves a list of all supported banks and their details. Requires OAuth2 authentication.
Response: [ { "bic": "CBEETAA", "name": "Commercial Bank of Ethiopia", "logo": "https://env-url/images/banks/cbe.png" }, { "bic": "YAYAETAA", "name": "YaYa Wallet", "logo": "https://env-url/images/banks/yaya.png" } ]
GET /api/merchant-categories
Retrieves a list of all supported merchant categories (MCC codes) and their descriptions. Requires OAuth2 authentication.
Response: [ { "code": "5411", "description": "Retail stores primarily selling food and household items" }, { "code": "5812", "description": "Establishments primarily engaged in preparing and serving meals" }, { "code": "5311", "description": "Retail stores selling a wide variety of merchandise" } ]
Below is a comprehensive list of all fields used in the payment system, their purposes, and important notes about their usage.
Field | Description | Notes |
---|---|---|
Request Fields | Required fields in the request payload: | |
bankBic | Bank Identifier Code for routing payments. |
|
bankAccount | Account identifier for receiving payments. |
|
amount | Payment amount in ETB. |
|
paymentReference | Unique identifier for the payment. |
|
feeOnMerchant | Determines who pays the processing fee. |
|
callbackUrl | URL for payment status updates. |
|
Response Fields | Important fields in the response: | |
urlSlug | Short identifier for payment URLs. |
|
processingFee | Fee charged for processing the payment. |
|
qrCode | QR code for mobile payment. |
|
paymentLink | URL for the payment page. |
|
Our system sends payment status updates to your callback URL. It's recommended to use a unique callback URL for each payment intent to better track and manage payments.
POST your_callback_url Headers: Content-Type: application/json X-Payment-Signature: generated_signature Request Body: { "paymentId": "7d31bd3f-6223-4b14-b174-584913f39323", "paymentReference": "INV-005", "amount": 1000, "isFeeOnMerchant": true, "processingFee": "20.00", "status": "paid", "bankBic": "YAYAETAA", "bankAccount": "antenehgebey", "paymentCode": "CAE8CD8E4901", "transactionId": "TXN-7497B30295A1D9AD", "paymentLink": "https://pay.yayawallet.com/p/CAE8CD8E4901", "thankYouUrl": "https://env-url/ty/CAE8CD8E4901", "returnUrl": "https://yourwebsite.com/thank-you", "timestamp": "2025-06-01T08:31:46.091Z", "createdAt": "2025-06-01T08:30:08.046Z", "updatedAt": "2025-06-01T08:31:46.088Z" }
To ensure the callback is legitimate, validate the signature using the following process:
paymentId + paymentReference + amount
Example validation in Node.js: const crypto = require('crypto'); function validateSignature(paymentId, paymentReference, amount, signature, clientSecret) { const data = `${paymentId}${paymentReference}${amount}`; const expectedSignature = crypto.createHmac('sha256', clientSecret) .update(data) .digest('hex'); return signature === expectedSignature; } // Example usage in Express middleware app.post('/payment-callback', (req, res) => { const signature = req.headers['x-payment-signature']; const { paymentId, paymentReference, amount } = req.body; if (!validateSignature(paymentId, paymentReference, amount, signature, process.env.CLIENT_SECRET)) { return res.status(401).json({ error: 'Invalid signature' }); } // Process the payment notification // ... res.status(200).json({ received: true }); });