Developer documentation

Build payments with Yeti API.

Use one clean server-side integration to initiate payments, receive instant payment notifications, and verify transaction status before delivering an order.

Test and live modes Hosted QR checkout NPR payments
Integration flow

Quick start

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.

01

Create API keys

Generate matching test or live credentials from the merchant dashboard.

02

Initiate payment

Send the order, amount, credentials, and callback URLs from your server.

03

Redirect customer

Redirect the browser to the returned redirect_url to show the QR page.

04

Verify and deliver

Confirm the payment through IPN or payment status before fulfilling the order.

Environment matching: use test keys with the test endpoint and live keys with the live endpoint. Rotated or inactive keys are rejected.
Overview

Introduction

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.

Never expose your secret key in frontend JavaScript. Initiate and verify payments from your backend server.
Configuration

Supported currency

CurrencyCodeSymbolStatus
Nepalese RupeeNPRरुSupported
Authentication

Get API keys

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.

.env example
YETI_PUBLIC_KEY=your_public_key
YETI_SECRET_KEY=your_secret_key
YETI_MODE=test
Rotate compromised keys immediately. Do not commit credentials to Git or include them in screenshots, logs, or support messages.
Payments API

Initiate payment

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.

POST https://client.yetiapi.com/test/payment/initiate TEST
POST https://client.yetiapi.com/payment/initiate LIVE

Request parameters

ParameterTypeRequirementDescription
public_keystringRequiredYour merchant public API key.
secret_keystringRequiredYour merchant secret API key.
identifierstringRequiredA unique identifier generated by your system for this payment.
currencystringRequiredCurrency code. Use NPR.
amountdecimalRequiredTotal payment amount.
detailsstringRequiredShort description shown for the payment.
ipn_urlURLRequiredYour server endpoint for instant payment notifications.
success_urlURLRequiredBrowser redirect after a successful checkout.
cancel_urlURLRequiredBrowser redirect when checkout is cancelled.
site_namestringOptionalYour business or website name.
site_logoURLOptionalPublic HTTPS URL for your logo.
customer[first_name]stringOptionalCustomer first name.
customer[last_name]stringOptionalCustomer last name.
customer[email]stringOptionalCustomer email address.
customer[mobile]stringOptionalCustomer mobile number.

PHP example

initiate-payment.php
<?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);

Example response

Success response
{
  "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,..."
  }
}
Next step: save trx_number, then redirect the customer to redirect_url. The hosted page displays the payment QR.
Response fieldDescription
trx_numberUnique Yeti transaction reference. Save it with your local order.
redirect_urlHosted checkout URL. Redirect the customer's browser here.
sdk_urlCheckout URL for SDK or embedded integration flows.
qr.qr_stringRaw QR payload for custom QR rendering.
qr.qr_image_base64Ready-to-display Base64 PNG QR image.
Callbacks

Validate payment and IPN

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.

FieldDescription
statusFinal or current payment state.
identifierYour original unique order identifier.
signatureHash signature used to validate the notification.
dataPayment data such as amount, currency, charges, and transaction reference.
Laravel-style IPN verification
$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.
}
Make the IPN handler idempotent. Receiving the same valid callback more than once must not deliver the same order twice.
Verification

Check payment status

Use the status endpoint when the IPN is delayed, when the customer returns to your site, or before manually resolving a pending order.

POST https://client.yetiapi.com/test/payment/payment-status TEST
POST https://client.yetiapi.com/payment/payment-status LIVE
ParameterTypeRequirementDescription
public_keystringRequiredYour public API key.
secret_keystringRequiredYour secret API key.
trx_numberstringRequiredThe transaction reference returned during initiation.
successThe payment has been confirmed.
pendingThe payment is awaiting confirmation.
failedThe payment failed or was cancelled.
Status response
{
  "status": "success",
  "data": {
    "trx_number": "encrypted_transaction_reference",
    "payment_status": "Success",
    "amount": "500.00",
    "currency": "NPR"
  }
}
Responses

Error handling

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.

Error response
{
  "status": "error",
  "message": [
    "Invalid API key"
  ]
}
Production readiness

Security checklist

CheckRecommendation
HTTPSUse HTTPS for all success, cancel, and IPN URLs.
SecretsKeep the secret key only on your backend and in protected environment variables.
VerificationVerify signatures and transaction status before order fulfilment.
Amount matchingConfirm the paid amount and currency match the stored order.
IdempotencyProcess each payment only once, even if callbacks are retried.
LoggingLog transaction references and errors, but redact credentials and sensitive customer data.
Launch workflow

Testing workflow

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.

Recommended: keep separate test and production credentials, database records, and log channels.