ShopnoPay API

ShopnoPay আপনার ফোনে আসা অফিশিয়াল মোবাইল-ওয়ালেট “টাকা পেয়েছেন” SMS থেকে শুধু trx_id, amount, sender_number সার্ভারে নেয়। কাস্টমার পেমেন্ট পেজে TrxID দিলে অথবা SMS আসলে সার্ভার সেটি ইনভয়েসের সাথে মিলিয়ে পেমেন্ট কনফার্ম করে ও আপনার ওয়েবসাইটে Webhook পাঠায়।

BASEhttps://shopnopuron.xyz.megalifebd.com/api/v1

সব রিকোয়েস্ট ও রেসপন্স JSON। সবসময় HTTPS ব্যবহার করুন।

অথেন্টিকেশন — Brand Key + API Key + Secret Key

আপনার ওয়েবসাইট/সার্ভার থেকে প্রতিটি রিকোয়েস্টে তিনটি হেডার একসাথে দিতে হবে। একটিও ভুল বা অনুপস্থিত হলে 401 আসবে। (ShopnoPay মোবাইল অ্যাপ আলাদা — সেখানে শুধু একটি Device Key লাগে, নিচে দেখুন।)

হেডারকীকোথায় রাখবেন
X-Brand-Keyব্র্যান্ড শনাক্তকারী (br_…)সার্ভার — প্রকাশ্য হতে পারে
X-API-KeyAPI অ্যাক্সেস কী (ak_…)সার্ভার
X-Secret-Keyগোপন কী (sk_…)শুধু আপনার সার্ভারে। ব্রাউজার/ফ্রন্টএন্ডে কখনো নয়
HTTP
GET https://shopnopuron.xyz.megalifebd.com/api/v1/ping
X-Brand-Key: br_xxxxxxxxxxxx
X-API-Key: ak_xxxxxxxxxxxxxxxx
X-Secret-Key: sk_xxxxxxxxxxxxxxxx
Secret Key শুধু একবার দেখানো হয়। ড্যাশবোর্ডে ব্র্যান্ড তৈরি বা Secret রিজেনারেট করার সময় কপি করে নিন — আমরা শুধু এর হ্যাশ রাখি, হারালে নতুন তৈরি করতে হবে।

সামঞ্জস্যের জন্য Authorization: Bearer <API Key> হেডারও API Key হিসেবে গ্রহণ করা হয়, তবে Brand Key ও Secret Key তখনও বাধ্যতামূলক।

লাইভ বনাম স্যান্ডবক্স

একই ক্রেডেনশিয়াল দুই মোডে চলে। স্যান্ডবক্স ডেটা লাইভ ডেটা থেকে সম্পূর্ণ আলাদা এবং প্ল্যান কোটায় গণনা হয় না।

মোডBase URL
Livehttps://shopnopuron.xyz.megalifebd.com/api/v1
Sandboxhttps://shopnopuron.xyz.megalifebd.com/api/v1/sandbox

লাইভ এন্ডপয়েন্টে সক্রিয় প্ল্যান ও অন্তত একটি রিসিভিং ওয়ালেট নম্বর প্রয়োজন; স্যান্ডবক্সে নয়।

এরর ও স্ট্যাটাস

JSON
{
  "success": false,
  "error": "invalid_credentials",
  "message": "Brand Key, API Key and Secret Key do not match."
}
HTTPerrorঅর্থ
401missing_credentials / invalid_credentialsতিনটি কি সঠিকভাবে দেওয়া হয়নি
402plan_required / quota_exceededপ্ল্যান নেই/মেয়াদোত্তীর্ণ বা মাসিক লিমিট শেষ
403brand_suspended / account_suspended / device_limit / demo_brandঅ্যাক্সেস নিষিদ্ধ
404not_foundপেমেন্ট পাওয়া যায়নি
422invalid_request / invalid_*প্যারামিটার ভুল
429rate_limitedঅতিরিক্ত রিকোয়েস্ট

পেমেন্ট স্ট্যাটাস

pending → completed | expired | cancelled | failed

Create Payment

POST/payments
প্যারামিটারটাইপবিবরণ
amount *number১ থেকে ১০,০০,০০০
referencestringআপনার অর্ডার আইডি (সর্বোচ্চ ১০০ অক্ষর)
redirect_urlurlসফল পেমেন্টের পর কাস্টমারকে এখানে পাঠানো হবে (ব্র্যান্ডের ডিফল্ট থাকলে ঐচ্ছিক)
cancel_urlurlবাতিল করলে
webhook_urlurlএই ইনভয়েসের জন্য আলাদা Webhook (ব্র্যান্ডের URL ওভাররাইড করে)
customer_name / customer_email / customer_phonestringঐচ্ছিক
metadataobjectআপনার নিজস্ব ডেটা (≤ ২০০০ বাইট), Webhook-এ ফেরত আসে
CURL
curl -X POST https://shopnopuron.xyz.megalifebd.com/api/v1/payments \
  -H "X-Brand-Key: br_xxxxxxxx" -H "X-API-Key: ak_xxxxxxxx" -H "X-Secret-Key: sk_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"amount": 1250, "reference": "ORDER-1001", "redirect_url": "https://shop.com/thanks"}'
RESPONSE 201
{
  "success": true,
  "payment": {
    "invoice_id": "INV3F9A1C2B7D4E5",
    "reference": "ORDER-1001",
    "amount": 1250,
    "currency": "BDT",
    "status": "pending",
    "expires_at": "2026-10-11 20:45:00",
    "payment_url": "https://shopnopuron.xyz.megalifebd.com/pay/INV3F9A1C2B7D4E5"
  }
}

কাস্টমারকে payment_url-এ পাঠান।

Retrieve Payment

GET/payments?invoice_id=INV…

অথবা ?reference=ORDER-1001 দিয়ে সর্বশেষ মিলে যাওয়া পেমেন্ট।

Verify Payment

POST/verify

কাস্টমার রিডাইরেক্টে ফিরে আসলে সবসময় সার্ভার থেকে ভেরিফাই করুন — রিডাইরেক্ট URL-এর প্যারামিটারকে বিশ্বাস করবেন না।

JSON
// শুধু স্ট্যাটাস দেখতে
{ "invoice_id": "INV3F9A1C2B7D4E5" }

// নির্দিষ্ট TrxID এই ইনভয়েসের সাথে মেলাতে (আপনার নিজের ফর্মে TrxID নিলে)
{ "invoice_id": "INV3F9A1C2B7D4E5", "trx_id": "9GK4X2LM" }
RESPONSE
{ "success": true, "verified": true, "reason": null, "payment": { "status": "completed", "trx_id": "9GK4X2LM", ... } }

verified শুধু তখনই true যখন status completed। রিসিভড অ্যামাউন্ট ইনভয়েসের চেয়ে কম হলে মেলানো হয় না।

ইন্টিগ্রেশন ফ্লো — PHP উদাহরণ

PHP
<?php
// 1) checkout.php — ইনভয়েস বানিয়ে কাস্টমারকে পাঠান
function shopnopay($method, $path, $body = null) {
    $ch = curl_init('https://shopnopuron.xyz.megalifebd.com/api/v1' . $path);
    curl_setopt_array($ch, [
        CURLOPT_CUSTOMREQUEST => $method, CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => ['X-Brand-Key: ' . BRAND_KEY, 'X-API-Key: ' . API_KEY, 'X-Secret-Key: ' . SECRET_KEY, 'Content-Type: application/json'],
        CURLOPT_POSTFIELDS => $body ? json_encode($body) : null,
    ]);
    return json_decode(curl_exec($ch), true);
}
$r = shopnopay('POST', '/payments', ['amount' => $order['total'], 'reference' => $order['id'], 'redirect_url' => 'https://shop.com/thanks.php']);
header('Location: ' . $r['payment']['payment_url']);

// 2) thanks.php — redirect-এ ফিরলে সার্ভার থেকে নিশ্চিত হোন
$r = shopnopay('POST', '/verify', ['invoice_id' => $_GET['invoice_id']]);
if ($r['verified']) { /* অর্ডার পেইড মার্ক করুন */ }

Webhook

ড্যাশবোর্ডের ব্র্যান্ড সেটিংসে Webhook URL দিন (বা প্রতিটি ইনভয়েসে webhook_url)। ইভেন্ট:

payment.completed · payment.expired · payment.failed · payment.cancelled

POST → YOUR URL
POST /webhook HTTP/1.1
Content-Type: application/json
X-ShopnoPay-Event: payment.completed
X-ShopnoPay-Timestamp: 1760186000
X-ShopnoPay-Signature: sha256=3f1c…e9

{
  "id": "evt_8f2a91c4d7e03b65",
  "event": "payment.completed",
  "created": 1760186000,
  "data": {
    "invoice_id": "INV3F9A1C2B7D4E5",
    "reference": "ORDER-1001",
    "amount": 1250,
    "currency": "BDT",
    "status": "completed",
    "provider": "bkash",
    "trx_id": "9GK4X2LM",
    "sender_number": "01712345678",
    "metadata": null,
    "sandbox": false,
    "paid_at": "2026-10-11 20:15:03",
    "brand_key": "br_xxxxxxxx"
  }
}

আপনার এন্ডপয়েন্ট দ্রুত HTTP 2xx রিটার্ন করবে (৫ সেকেন্ডের মধ্যে)। একই ইভেন্ট একাধিকবার আসতে পারে — data.invoice_id দিয়ে ইডেম্পোটেন্ট রাখুন।

সিগনেচার ভেরিফাই

সিগনেচার = HMAC_SHA256(webhook_secret, timestamp + "." + raw_body)। Webhook Secret (whsec_…) ড্যাশবোর্ডে ব্র্যান্ড পেজে পাবেন — এটি Secret Key থেকে আলাদা।

$raw = file_get_contents('php://input');
$ts  = $_SERVER['HTTP_X_SHOPNOPAY_TIMESTAMP'] ?? '';
$sig = $_SERVER['HTTP_X_SHOPNOPAY_SIGNATURE'] ?? '';
$expected = 'sha256=' . hash_hmac('sha256', $ts . '.' . $raw, WEBHOOK_SECRET);

if (!hash_equals($expected, $sig) || abs(time() - (int)$ts) > 300) {
    http_response_code(401); exit('bad signature');
}
$event = json_decode($raw, true);
if ($event['event'] === 'payment.completed') {
    // $event['data']['reference'] অর্ডারটি পেইড করুন
}
http_response_code(200);

রিট্রাই ও ডেলিভারি লগ

2xx ছাড়া অন্য রেসপন্স বা টাইমআউট হলে আমরা আবার চেষ্টা করি: ১ মিনিট → ৫ মিনিট → ৩০ মিনিট → ২ ঘণ্টা → ১২ ঘণ্টা। এরপরও ব্যর্থ হলে ইভেন্ট failed হয় — ড্যাশবোর্ডের Webhook লগ থেকে ম্যানুয়ালি রিসেন্ড করা যায়। Webhook URL অবশ্যই পাবলিক হোস্টে হতে হবে (লোকালহোস্ট/প্রাইভেট IP ব্লক করা হয়)।

মোবাইল অ্যাপ — Ping

GET/ping

অ্যাপ: শুধু X-Device-Key: dk_… হেডার (ড্যাশবোর্ড → ডিভাইস থেকে নেওয়া)। সার্ভার থেকে কল করলে ৩টি কি। অ্যাপের “Test connection” এ ব্যবহৃত হয়। ঐচ্ছিক হেডার: X-Device-Id (অ্যাপ-জেনারেটেড ইউনিক আইডি), X-Device-Name, X-App-Version — এগুলো দিলে ফোনটি ড্যাশবোর্ডের “ডিভাইস” তালিকায় দেখা যায়।

মোবাইল অ্যাপ — Stats

হেডার: X-Device-Key।

GET/stats
RESPONSE
{
  "success": true,
  "total": 42, "processed": 37, "pending": 4, "failed": 1,
  "amount": 52340.5,
  "week": [[3,1,0],[5,0,0],[4,1,0],[6,0,1],[7,1,0],[5,0,0],[7,1,0]]
}

week = শেষ ৭ দিন (পুরোনো→নতুন), প্রতিটি [processed, pending, failed]।

মোবাইল অ্যাপ — Transactions

হেডার: X-Device-Key (অ্যাপ) অথবা ৩টি কি (সার্ভার)। ডিভাইস কি শুধু ping, stats, transactions এন্ডপয়েন্টে চলে — পেমেন্ট তৈরি/ভেরিফাই করা যায় না।

POST/transactions

অ্যাপ প্রতিটি “টাকা পেয়েছেন” SMS থেকে TrxID, পরিমাণ, প্রেরকের নম্বর ও প্রোভাইডারের নাম পাঠায়:

JSON
{ "trx_id": "9GK4X2LM", "amount": 1250.00, "sender_number": "01712345678", "provider": "bKash" }
RESPONSE 201
{ "success": true, "id": 981, "status": "processed", "matched_payment": 77 }

একই trx_id আবার পাঠালে 200 ও \"duplicate\": true — অ্যাপ নিরাপদে রিট্রাই করতে পারে। অপশনাল provider (bkash, nagad…) দেওয়া যায়। ইনভয়েসে মিল পেলে সাথে সাথে পেমেন্ট completed হয় ও Webhook যায়।

GET/transactions?limit=50

স্যান্ডবক্স ও সিমুলেটর

Base URL-এ /sandbox যোগ করুন (https://shopnopuron.xyz.megalifebd.com/api/v1/sandbox/payments)। এর পেমেন্ট URL-এ “সিমুলেট” বাটন থাকে, অথবা API দিয়ে:

POST/sandbox/simulate
JSON
{ "invoice_id": "SBX…", "provider": "bkash" }

এটি একটি ফেক SMS ট্রানজ্যাকশন তৈরি করে পেমেন্ট কনফার্ম করে ও Webhook পাঠায়। পাবলিক ডেমো ক্রেডেনশিয়াল স্যান্ডবক্স পেজে আছে।

রেট লিমিট

প্রতি ব্র্যান্ডে ২৪০ রিকোয়েস্ট/মিনিট। ভুল ক্রেডেনশিয়ালে প্রতি IP-তে ১০ মিনিটে ৩০ বার চেষ্টা করা যায়। মাসিক পেমেন্ট/ট্রানজ্যাকশন লিমিট প্ল্যান অনুযায়ী (আনলিমিটেড প্ল্যানে নেই)।