{"openapi":"3.1.0","info":{"title":"Paylinky API","version":"1.0.0","description":"Mobile Money and crypto payments in Africa. Hosted Page API (payment links) and Direct API. Use plk_test_ keys for the sandbox (numbers ending 000000001 success, 2 pending, 3 failed, 4 OTP 000000, 5 cancelled). Live keys require KYC approval and manual activation. Full docs: https://paylinky.vercel.app/llms-full.txt"},"servers":[{"url":"https://paylinky.vercel.app/api/v1"}],"security":[{"bearer":[]}],"paths":{"/countries":{"get":{"summary":"List active countries and Mobile Money operators","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Country"}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/crypto/assets":{"get":{"summary":"List active crypto assets","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CryptoAsset"}}}}}}}},"/fees":{"get":{"summary":"Fee configuration","responses":{"200":{"description":"OK"}}}},"/balance":{"get":{"summary":"Wallet balances","responses":{"200":{"description":"OK"}}}},"/collect":{"post":{"summary":"Create a Mobile Money collection (Direct API)","description":"202 pending (USSD push / Wave with wave_url). 400 otp_required: re-send with reference (from the error) and otp. Sandbox: scenario by last digit of phone.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectRequest"}}}},"responses":{"200":{"description":"Final result or idempotent replay","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Transaction"}}}},"202":{"description":"Pending","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Transaction"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/crypto/collect":{"post":{"summary":"Create a crypto payment","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CryptoCollectRequest"}}}},"responses":{"202":{"description":"Pending, with address and network","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Transaction"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/transaction/{id}":{"get":{"summary":"Get a transaction by transaction_id, reference or merchant_reference","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Transaction"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/transactions":{"get":{"summary":"List transactions","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","maximum":100}},{"name":"status","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/payment-links":{"post":{"summary":"Create a hosted payment link (Hosted Page API)","parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentLinkRequest"}}}},"responses":{"200":{"description":"Reused (idempotent)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentLink"}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentLink"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/payment-links/{id}":{"get":{"summary":"Get a payment link by id or slug","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentLink"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/sandbox/simulate":{"post":{"summary":"Sandbox only: finish a pending test transaction and fire the webhook","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SimulateRequest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Transaction"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"webhooks":{"paymentEvent":{"post":{"summary":"payment.completed / payment.failed","description":"Headers: X-Paylinky-Event-Id, X-Paylinky-Timestamp, X-Paylinky-Signature = sha256=HMAC_SHA256_hex(whsec_secret, timestamp + '.' + rawBody).","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Acknowledge with any 2xx"}}}}},"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"plk_test_… or plk_live_…"}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"reference":{"type":"string"},"ussd_code":{"type":"string"}},"required":["error","message"]},"Country":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"currency":{"type":"string"},"operators":{"type":"array","items":{"type":"string"}},"unavailable_operators":{"type":"array","items":{"type":"string"}}}},"CryptoAsset":{"type":"object","properties":{"asset_code":{"type":"string"},"name":{"type":"string"},"network":{"type":"string"},"symbol":{"type":"string"}}},"CollectRequest":{"type":"object","required":["amount","currency","country_code","operator","phone"],"properties":{"amount":{"type":"number"},"currency":{"type":"string"},"country_code":{"type":"string"},"operator":{"type":"string","description":"Exact name from /countries"},"phone":{"type":"string"},"reference":{"type":"string","maxLength":191},"notify_url":{"type":"string"},"otp":{"type":"string"}}},"CryptoCollectRequest":{"type":"object","required":["amount","asset_code","customer"],"properties":{"amount":{"type":["string","number"]},"currency":{"type":"string","default":"USDT"},"asset_code":{"type":"string"},"reference":{"type":"string"},"notify_url":{"type":"string"},"customer":{"type":"object","required":["email","firstName","lastName"],"properties":{"email":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"}}}}},"PaymentLinkRequest":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string"},"amount":{"type":"number"},"currency":{"type":"string"},"is_fixed_amount":{"type":"boolean","default":true},"allowed_countries":{"type":"array","items":{"type":"string"}},"expires_in_minutes":{"type":["integer","null"],"default":30},"reference":{"type":"string"},"success_url":{"type":"string"},"cancel_url":{"type":"string"}}},"PaymentLink":{"type":"object","properties":{"payment_id":{"type":"string"},"slug":{"type":"string"},"payment_link":{"type":"string"},"status":{"enum":["active","paid","expired","disabled"]},"amount":{"type":["number","null"]},"currency":{"type":"string"},"expires_at":{"type":["string","null"]},"reused":{"type":"boolean"}}},"SimulateRequest":{"type":"object","required":["transaction_id"],"properties":{"transaction_id":{"type":"string"},"status":{"enum":["success","failed","cancelled"]}}},"Transaction":{"type":"object","properties":{"transaction_id":{"type":"string"},"reference":{"type":"string"},"merchant_reference":{"type":["string","null"]},"status":{"enum":["pending","success","failed","cancelled","expired","refunded"]},"payment_method":{"enum":["mobile_money","crypto"]},"amount":{"type":"number"},"fee_amount":{"type":"number"},"credited_amount":{"type":"number"},"currency":{"type":"string"},"country_code":{"type":"string"},"operator":{"type":"string"},"phone":{"type":"string"},"flow":{"type":"string"},"wave_url":{"type":"string"},"asset_code":{"type":"string"},"network":{"type":"string"},"address":{"type":"string"},"memo":{"type":["string","null"]},"sandbox":{"type":"boolean"},"expires_at":{"type":["string","null"]}}},"WebhookEvent":{"allOf":[{"$ref":"#/components/schemas/Transaction"},{"type":"object","properties":{"event":{"enum":["payment.completed","payment.failed"]},"timestamp":{"type":"string"}}}]}}}}