Create API keys
Generate matching test or live credentials from the merchant dashboard.
Use one clean server-side integration to initiate payments, receive instant payment notifications, and verify transaction status before delivering an order.
Yeti API returns a JSON response when a payment is created. Your server must read that response and redirect the customer's browser to redirect_url, which opens the hosted QR checkout page.
Generate matching test or live credentials from the merchant dashboard.
Send the order, amount, credentials, and callback URLs from your server.
Redirect the browser to the returned redirect_url to show the QR page.
Confirm the payment through IPN or payment status before fulfilling the order.
Yeti API provides HTTP endpoints for accepting digital payments in Nepal. Requests are sent from your server, and payment initiation responses are returned in JSON. After a successful initiation, redirect the customer to the returned hosted checkout URL to display the payment QR.
Build and test your complete flow using the test endpoint. Move to the live endpoint only after payment initiation, redirects, IPN handling, and status verification have all been confirmed.
| Currency | Code | Symbol | Status |
|---|---|---|---|
| Nepalese Rupee | NPR | रु | Supported |
Sign in to your merchant dashboard and open the API credentials area. Generate separate credentials for test and live transactions, then store them in your server environment file.
YETI_PUBLIC_KEY=your_public_key
YETI_SECRET_KEY=your_secret_key
YETI_MODE=test
Create a payment session by sending a server-side POST request with your credentials, order identifier, amount, customer-facing description, and callback URLs. The endpoint returns JSON; it does not directly render the checkout page.
| Parameter | Type | Requirement | Description |
|---|---|---|---|
| public_key | string | Required | Your merchant public API key. |
| secret_key | string | Required | Your merchant secret API key. |
| identifier | string | Required | A unique identifier generated by your system for this payment. |
| currency | string | Required | Currency code. Use NPR. |
| amount | decimal | Required | Total payment amount. |
| details | string | Required | Short description shown for the payment. |
| ipn_url | URL | Required | Your server endpoint for instant payment notifications. |
| success_url | URL | Required | Browser redirect after a successful checkout. |
| cancel_url | URL | Required | Browser redirect when checkout is cancelled. |
| site_name | string | Optional | Your business or website name. |
| site_logo | URL | Optional | Public HTTPS URL for your logo. |
| customer[first_name] | string | Optional | Customer first name. |
| customer[last_name] | string | Optional | Customer last name. |
| customer[email] | string | Optional | Customer email address. |
| customer[mobile] | string | Optional | Customer mobile number. |
<?php
$publicKey = getenv('YETI_PUBLIC_KEY');
$secretKey = getenv('YETI_SECRET_KEY');
$payload = [
'public_key' => $publicKey,
'secret_key' => $secretKey,
'identifier' => 'ORDER-' . time(),
'currency' => 'NPR',
'amount' => 500.00,
'details' => 'Payment for customer order',
'ipn_url' => 'https://example.com/yeti/ipn.php',
'success_url' => 'https://example.com/payment/success.php',
'cancel_url' => 'https://example.com/payment/cancel.php',
'site_name' => 'Example Store',
'customer' => [
'first_name' => 'Ram',
'last_name' => 'Karki',
'email' => 'customer@example.com',
'mobile' => '9800000000',
],
];
$ch = curl_init(
'https://client.yetiapi.com/test/payment/initiate'
);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($payload),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Content-Type: application/x-www-form-urlencoded',
],
]);
$response = curl_exec($ch);
if ($response === false) {
throw new RuntimeException(curl_error($ch));
}
curl_close($ch);
$result = json_decode($response, true);
if (
is_array($result) &&
($result['status'] ?? '') === 'success' &&
!empty($result['redirect_url'])
) {
header('Location: ' . $result['redirect_url']);
exit;
}
header('Content-Type: application/json');
echo json_encode($result, JSON_PRETTY_PRINT);
{
"status": "success",
"message": [
"Payment initiated"
],
"trx_number": "yeti_trx_...",
"redirect_url": "https://client.yetiapi.com/pay/yeti_trx_...",
"sdk_url": "https://client.yetiapi.com/pay/yeti_trx_...",
"qr": {
"qr_string": "000201010212...",
"qr_image_base64": "data:image/png;base64,..."
}
}
trx_number, then redirect the customer to redirect_url. The hosted page displays the payment QR.| Response field | Description |
|---|---|
| trx_number | Unique Yeti transaction reference. Save it with your local order. |
| redirect_url | Hosted checkout URL. Redirect the customer's browser here. |
| sdk_url | Checkout URL for SDK or embedded integration flows. |
| qr.qr_string | Raw QR payload for custom QR rendering. |
| qr.qr_image_base64 | Ready-to-display Base64 PNG QR image. |
Yeti API sends a POST request to your ipn_url when the payment status changes. Treat the callback as a notification, then verify its signature and transaction details before delivering the product.
| Field | Description |
|---|---|
| status | Final or current payment state. |
| identifier | Your original unique order identifier. |
| signature | Hash signature used to validate the notification. |
| data | Payment data such as amount, currency, charges, and transaction reference. |
$status = $request->input('status');
$identifier = $request->input('identifier');
$signature = $request->input('signature');
$data = $request->input('data', []);
$signaturePayload = ($data['amount'] ?? '') . $identifier;
$expectedSignature = strtoupper(hash_hmac(
'sha256',
$signaturePayload,
config('services.yeti.secret_key')
));
if (
$status === 'success' &&
hash_equals($expectedSignature, $signature)
) {
// Mark the matching order as paid once.
}
Use the status endpoint when the IPN is delayed, when the customer returns to your site, or before manually resolving a pending order.
| Parameter | Type | Requirement | Description |
|---|---|---|---|
| public_key | string | Required | Your public API key. |
| secret_key | string | Required | Your secret API key. |
| trx_number | string | Required | The transaction reference returned during initiation. |
{
"status": "success",
"data": {
"trx_number": "encrypted_transaction_reference",
"payment_status": "Success",
"amount": "500.00",
"currency": "NPR"
}
}
Handle API errors as normal application states. Display a safe message to the customer and log the technical response on your server without recording secret keys.
{
"status": "error",
"message": [
"Invalid API key"
]
}
| Check | Recommendation |
|---|---|
| HTTPS | Use HTTPS for all success, cancel, and IPN URLs. |
| Secrets | Keep the secret key only on your backend and in protected environment variables. |
| Verification | Verify signatures and transaction status before order fulfilment. |
| Amount matching | Confirm the paid amount and currency match the stored order. |
| Idempotency | Process each payment only once, even if callbacks are retried. |
| Logging | Log transaction references and errors, but redact credentials and sensitive customer data. |
Use test credentials only with /test/payment/initiate and the test status endpoint. Test a successful payment, cancellation, invalid credentials, duplicate IPN delivery, delayed IPN delivery, and a manual status check. Confirm that each case updates the correct order and never delivers twice.