{"openapi":"3.1.0","info":{"title":"TachoPay Partner API","version":"1.0.0","description":"B2B partner API for mobile recharge & bill payment across IN/BD/SG corridors.\n\nAuth: Bearer `tpk_live_*` (production) or `tpk_test_*` (sandbox).","contact":{"email":"developers@tachopay.com","name":"TachoPay Developers"}},"servers":[{"url":"https://api.tachopay.com/v1/partner","description":"Production + sandbox (token decides)"}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"tpk_<env>_<32>"}},"schemas":{"Balance":{"type":"object","properties":{"available":{"type":"string","example":"8742.50"},"currency":{"type":"string","enum":["INR","BDT","SGD"]},"corridor":{"type":"string","enum":["IN","BD","SG"]},"updated_at":{"type":"string","format":"date-time"},"environment":{"type":"string","enum":["live","sandbox"]}}},"Operator":{"type":"object","properties":{"id":{"type":"integer","example":421},"api_operator_id":{"type":"string","example":"GT-3"},"name":{"type":"string","example":"Grameenphone"},"category":{"type":"string"},"min_amount":{"type":"string","example":"20.00"},"max_amount":{"type":"string","example":"1000.00"},"local_currency":{"type":"string"}}},"TopupRequest":{"type":"object","required":["operator_id","phone","amount"],"properties":{"operator_id":{"type":"integer"},"phone":{"type":"string","example":"8801712340001"},"amount":{"type":"number","example":100},"reference":{"type":"string","description":"Your internal reference (echoed back)"}}},"TopupResponse":{"type":"object","properties":{"order_id":{"type":"string","example":"TP202600007"},"status":{"type":"string","enum":["PENDING"]},"amount_local":{"type":"string"},"currency":{"type":"string"},"balance_after":{"type":"string"},"reference":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time"}}},"BillInfo":{"type":"object","properties":{"biller_id":{"type":"integer"},"biller_name":{"type":"string"},"consumer_number":{"type":"string"},"customer_name":{"type":"string"},"amount":{"type":"string"},"currency":{"type":"string"},"due_date":{"type":"string","format":"date"},"bill_period":{"type":"string","example":"2026-06"},"bill_reference":{"type":"string"}}},"TransactionStatus":{"type":"object","properties":{"order_id":{"type":"string"},"status":{"type":"string","enum":["PENDING","SUCCESS","FAILED"]},"amount_local":{"type":"string"},"currency":{"type":"string"},"operator_ref":{"type":"string","nullable":true},"settled_at":{"type":"string","format":"date-time","nullable":true},"refunded_at":{"type":"string","format":"date-time","nullable":true}}},"Error":{"type":"object","properties":{"error":{"type":"string","example":"insufficient_balance"},"detail":{"type":"string","nullable":true}}}}},"security":[{"BearerAuth":[]}],"paths":{"/balance":{"get":{"summary":"Get wallet balance","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Balance"}}}},"401":{"description":"Invalid or missing API key"}}}},"/operators":{"get":{"summary":"List operators in your corridor","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"corridor":{"type":"string"},"count":{"type":"integer"},"operators":{"type":"array","items":{"$ref":"#/components/schemas/Operator"}}}}}}}}}},"/topup":{"post":{"summary":"Mobile prepaid recharge","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":8},"description":"Unique per request. Replay same key + same body → cached response."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopupRequest"}}}},"responses":{"200":{"description":"Optimistic PENDING — final status via webhook or GET /transactions/:order_id","headers":{"Idempotent-Replay":{"schema":{"type":"string"},"description":"\"true\" if served from cache"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopupResponse"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient balance"},"409":{"description":"Idempotency conflict — same key with different body"},"422":{"description":"Amount out of operator range"}}}},"/bill-info":{"post":{"summary":"Step 1 of bill payment — fetch outstanding amount","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["biller_id","consumer_number"],"properties":{"biller_id":{"type":"integer"},"consumer_number":{"type":"string"},"params":{"type":"object","additionalProperties":{"type":"string"}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillInfo"}}}}}}},"/pay-bill":{"post":{"summary":"Step 2 of bill payment — submit payment","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":8}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["biller_id","consumer_number","amount"],"properties":{"biller_id":{"type":"integer"},"consumer_number":{"type":"string"},"amount":{"type":"number"},"reference":{"type":"string"},"params":{"type":"object","additionalProperties":{"type":"string"}}}}}}},"responses":{"200":{"description":"PENDING","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopupResponse"}}}}}}},"/transactions/{order_id}":{"get":{"summary":"Get transaction status","parameters":[{"name":"order_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransactionStatus"}}}},"404":{"description":"Not found"}}}}}}