@atbas/m-mcp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (366) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +364 -0
  3. package/dist/builder/transaction-builder.d.ts +53 -0
  4. package/dist/builder/transaction-builder.d.ts.map +1 -0
  5. package/dist/builder/transaction-builder.js +159 -0
  6. package/dist/builder/transaction-builder.js.map +1 -0
  7. package/dist/catalogue/default-catalogue.d.ts +18 -0
  8. package/dist/catalogue/default-catalogue.d.ts.map +1 -0
  9. package/dist/catalogue/default-catalogue.js +21 -0
  10. package/dist/catalogue/default-catalogue.js.map +1 -0
  11. package/dist/catalogue/endpoints.d.ts +22 -0
  12. package/dist/catalogue/endpoints.d.ts.map +1 -0
  13. package/dist/catalogue/endpoints.js +24 -0
  14. package/dist/catalogue/endpoints.js.map +1 -0
  15. package/dist/catalogue/flows.d.ts +32 -0
  16. package/dist/catalogue/flows.d.ts.map +1 -0
  17. package/dist/catalogue/flows.js +64 -0
  18. package/dist/catalogue/flows.js.map +1 -0
  19. package/dist/catalogue/hash-options.d.ts +112 -0
  20. package/dist/catalogue/hash-options.d.ts.map +1 -0
  21. package/dist/catalogue/hash-options.js +151 -0
  22. package/dist/catalogue/hash-options.js.map +1 -0
  23. package/dist/catalogue/types.d.ts +279 -0
  24. package/dist/catalogue/types.d.ts.map +1 -0
  25. package/dist/catalogue/types.js +360 -0
  26. package/dist/catalogue/types.js.map +1 -0
  27. package/dist/codegen/generate.d.ts +14 -0
  28. package/dist/codegen/generate.d.ts.map +1 -0
  29. package/dist/codegen/generate.js +490 -0
  30. package/dist/codegen/generate.js.map +1 -0
  31. package/dist/codegen/languages/node.d.ts +3 -0
  32. package/dist/codegen/languages/node.d.ts.map +1 -0
  33. package/dist/codegen/languages/node.js +32 -0
  34. package/dist/codegen/languages/node.js.map +1 -0
  35. package/dist/codegen/languages/php.d.ts +3 -0
  36. package/dist/codegen/languages/php.d.ts.map +1 -0
  37. package/dist/codegen/languages/php.js +27 -0
  38. package/dist/codegen/languages/php.js.map +1 -0
  39. package/dist/codegen/languages/python.d.ts +3 -0
  40. package/dist/codegen/languages/python.d.ts.map +1 -0
  41. package/dist/codegen/languages/python.js +27 -0
  42. package/dist/codegen/languages/python.js.map +1 -0
  43. package/dist/codegen/renderer.d.ts +24 -0
  44. package/dist/codegen/renderer.d.ts.map +1 -0
  45. package/dist/codegen/renderer.js +59 -0
  46. package/dist/codegen/renderer.js.map +1 -0
  47. package/dist/codegen/types.d.ts +50 -0
  48. package/dist/codegen/types.d.ts.map +1 -0
  49. package/dist/codegen/types.js +5 -0
  50. package/dist/codegen/types.js.map +1 -0
  51. package/dist/config/credentials.d.ts +64 -0
  52. package/dist/config/credentials.d.ts.map +1 -0
  53. package/dist/config/credentials.js +216 -0
  54. package/dist/config/credentials.js.map +1 -0
  55. package/dist/config/environment.d.ts +23 -0
  56. package/dist/config/environment.d.ts.map +1 -0
  57. package/dist/config/environment.js +54 -0
  58. package/dist/config/environment.js.map +1 -0
  59. package/dist/core/dependencies.d.ts +43 -0
  60. package/dist/core/dependencies.d.ts.map +1 -0
  61. package/dist/core/dependencies.js +2 -0
  62. package/dist/core/dependencies.js.map +1 -0
  63. package/dist/core/registry.d.ts +33 -0
  64. package/dist/core/registry.d.ts.map +1 -0
  65. package/dist/core/registry.js +13 -0
  66. package/dist/core/registry.js.map +1 -0
  67. package/dist/core/server.d.ts +61 -0
  68. package/dist/core/server.d.ts.map +1 -0
  69. package/dist/core/server.js +90 -0
  70. package/dist/core/server.js.map +1 -0
  71. package/dist/dependencies.d.ts +28 -0
  72. package/dist/dependencies.d.ts.map +1 -0
  73. package/dist/dependencies.js +2 -0
  74. package/dist/dependencies.js.map +1 -0
  75. package/dist/diagnostics/diagnose.d.ts +43 -0
  76. package/dist/diagnostics/diagnose.d.ts.map +1 -0
  77. package/dist/diagnostics/diagnose.js +121 -0
  78. package/dist/diagnostics/diagnose.js.map +1 -0
  79. package/dist/domain/amount.d.ts +157 -0
  80. package/dist/domain/amount.d.ts.map +1 -0
  81. package/dist/domain/amount.js +275 -0
  82. package/dist/domain/amount.js.map +1 -0
  83. package/dist/domain/datetime.d.ts +95 -0
  84. package/dist/domain/datetime.d.ts.map +1 -0
  85. package/dist/domain/datetime.js +211 -0
  86. package/dist/domain/datetime.js.map +1 -0
  87. package/dist/domain/response-codes.d.ts +116 -0
  88. package/dist/domain/response-codes.d.ts.map +1 -0
  89. package/dist/domain/response-codes.js +380 -0
  90. package/dist/domain/response-codes.js.map +1 -0
  91. package/dist/domain/secure-hash.d.ts +78 -0
  92. package/dist/domain/secure-hash.d.ts.map +1 -0
  93. package/dist/domain/secure-hash.js +69 -0
  94. package/dist/domain/secure-hash.js.map +1 -0
  95. package/dist/domain/signature/jazzcash.d.ts +56 -0
  96. package/dist/domain/signature/jazzcash.d.ts.map +1 -0
  97. package/dist/domain/signature/jazzcash.js +214 -0
  98. package/dist/domain/signature/jazzcash.js.map +1 -0
  99. package/dist/domain/signature/registry.d.ts +69 -0
  100. package/dist/domain/signature/registry.d.ts.map +1 -0
  101. package/dist/domain/signature/registry.js +92 -0
  102. package/dist/domain/signature/registry.js.map +1 -0
  103. package/dist/domain/signature/scheme.d.ts +349 -0
  104. package/dist/domain/signature/scheme.d.ts.map +1 -0
  105. package/dist/domain/signature/scheme.js +398 -0
  106. package/dist/domain/signature/scheme.js.map +1 -0
  107. package/dist/domain/txn-ref.d.ts +76 -0
  108. package/dist/domain/txn-ref.d.ts.map +1 -0
  109. package/dist/domain/txn-ref.js +126 -0
  110. package/dist/domain/txn-ref.js.map +1 -0
  111. package/dist/domain/types.d.ts +45 -0
  112. package/dist/domain/types.d.ts.map +1 -0
  113. package/dist/domain/types.js +70 -0
  114. package/dist/domain/types.js.map +1 -0
  115. package/dist/errors.d.ts +84 -0
  116. package/dist/errors.d.ts.map +1 -0
  117. package/dist/errors.js +87 -0
  118. package/dist/errors.js.map +1 -0
  119. package/dist/gateway/checkout-form.d.ts +16 -0
  120. package/dist/gateway/checkout-form.d.ts.map +1 -0
  121. package/dist/gateway/checkout-form.js +103 -0
  122. package/dist/gateway/checkout-form.js.map +1 -0
  123. package/dist/gateway/checkout-output.d.ts +70 -0
  124. package/dist/gateway/checkout-output.d.ts.map +1 -0
  125. package/dist/gateway/checkout-output.js +199 -0
  126. package/dist/gateway/checkout-output.js.map +1 -0
  127. package/dist/gateway/guards.d.ts +37 -0
  128. package/dist/gateway/guards.d.ts.map +1 -0
  129. package/dist/gateway/guards.js +44 -0
  130. package/dist/gateway/guards.js.map +1 -0
  131. package/dist/gateway/http-client.d.ts +42 -0
  132. package/dist/gateway/http-client.d.ts.map +1 -0
  133. package/dist/gateway/http-client.js +153 -0
  134. package/dist/gateway/http-client.js.map +1 -0
  135. package/dist/gateway/rest-client.d.ts +42 -0
  136. package/dist/gateway/rest-client.d.ts.map +1 -0
  137. package/dist/gateway/rest-client.js +241 -0
  138. package/dist/gateway/rest-client.js.map +1 -0
  139. package/dist/gateway/transport.d.ts +31 -0
  140. package/dist/gateway/transport.d.ts.map +1 -0
  141. package/dist/gateway/transport.js +73 -0
  142. package/dist/gateway/transport.js.map +1 -0
  143. package/dist/index.d.ts +3 -0
  144. package/dist/index.d.ts.map +1 -0
  145. package/dist/index.js +75 -0
  146. package/dist/index.js.map +1 -0
  147. package/dist/install/cli.d.ts +38 -0
  148. package/dist/install/cli.d.ts.map +1 -0
  149. package/dist/install/cli.js +274 -0
  150. package/dist/install/cli.js.map +1 -0
  151. package/dist/install/harnesses.d.ts +74 -0
  152. package/dist/install/harnesses.d.ts.map +1 -0
  153. package/dist/install/harnesses.js +263 -0
  154. package/dist/install/harnesses.js.map +1 -0
  155. package/dist/knowledge/corpus.d.ts +15 -0
  156. package/dist/knowledge/corpus.d.ts.map +1 -0
  157. package/dist/knowledge/corpus.js +129 -0
  158. package/dist/knowledge/corpus.js.map +1 -0
  159. package/dist/knowledge/search.d.ts +29 -0
  160. package/dist/knowledge/search.d.ts.map +1 -0
  161. package/dist/knowledge/search.js +181 -0
  162. package/dist/knowledge/search.js.map +1 -0
  163. package/dist/knowledge/source.d.ts +60 -0
  164. package/dist/knowledge/source.d.ts.map +1 -0
  165. package/dist/knowledge/source.js +91 -0
  166. package/dist/knowledge/source.js.map +1 -0
  167. package/dist/knowledge/types.d.ts +40 -0
  168. package/dist/knowledge/types.d.ts.map +1 -0
  169. package/dist/knowledge/types.js +19 -0
  170. package/dist/knowledge/types.js.map +1 -0
  171. package/dist/paths.d.ts +26 -0
  172. package/dist/paths.d.ts.map +1 -0
  173. package/dist/paths.js +106 -0
  174. package/dist/paths.js.map +1 -0
  175. package/dist/prompts/integration-walkthrough.d.ts +11 -0
  176. package/dist/prompts/integration-walkthrough.d.ts.map +1 -0
  177. package/dist/prompts/integration-walkthrough.js +52 -0
  178. package/dist/prompts/integration-walkthrough.js.map +1 -0
  179. package/dist/prompts/register.d.ts +4 -0
  180. package/dist/prompts/register.d.ts.map +1 -0
  181. package/dist/prompts/register.js +4 -0
  182. package/dist/prompts/register.js.map +1 -0
  183. package/dist/registry.d.ts +14 -0
  184. package/dist/registry.d.ts.map +1 -0
  185. package/dist/registry.js +2 -0
  186. package/dist/registry.js.map +1 -0
  187. package/dist/resources/knowledge-resources.d.ts +5 -0
  188. package/dist/resources/knowledge-resources.d.ts.map +1 -0
  189. package/dist/resources/knowledge-resources.js +121 -0
  190. package/dist/resources/knowledge-resources.js.map +1 -0
  191. package/dist/resources/register.d.ts +4 -0
  192. package/dist/resources/register.d.ts.map +1 -0
  193. package/dist/resources/register.js +8 -0
  194. package/dist/resources/register.js.map +1 -0
  195. package/dist/server.d.ts +40 -0
  196. package/dist/server.d.ts.map +1 -0
  197. package/dist/server.js +56 -0
  198. package/dist/server.js.map +1 -0
  199. package/dist/telemetry/logger.d.ts +31 -0
  200. package/dist/telemetry/logger.d.ts.map +1 -0
  201. package/dist/telemetry/logger.js +67 -0
  202. package/dist/telemetry/logger.js.map +1 -0
  203. package/dist/telemetry/redaction.d.ts +88 -0
  204. package/dist/telemetry/redaction.d.ts.map +1 -0
  205. package/dist/telemetry/redaction.js +238 -0
  206. package/dist/telemetry/redaction.js.map +1 -0
  207. package/dist/tools/build-transaction-parameters.d.ts +10 -0
  208. package/dist/tools/build-transaction-parameters.d.ts.map +1 -0
  209. package/dist/tools/build-transaction-parameters.js +154 -0
  210. package/dist/tools/build-transaction-parameters.js.map +1 -0
  211. package/dist/tools/call-context.d.ts +47 -0
  212. package/dist/tools/call-context.d.ts.map +1 -0
  213. package/dist/tools/call-context.js +15 -0
  214. package/dist/tools/call-context.js.map +1 -0
  215. package/dist/tools/codegen-tools.d.ts +4 -0
  216. package/dist/tools/codegen-tools.d.ts.map +1 -0
  217. package/dist/tools/codegen-tools.js +131 -0
  218. package/dist/tools/codegen-tools.js.map +1 -0
  219. package/dist/tools/credential-tools.d.ts +32 -0
  220. package/dist/tools/credential-tools.d.ts.map +1 -0
  221. package/dist/tools/credential-tools.js +65 -0
  222. package/dist/tools/credential-tools.js.map +1 -0
  223. package/dist/tools/descriptor.d.ts +52 -0
  224. package/dist/tools/descriptor.d.ts.map +1 -0
  225. package/dist/tools/descriptor.js +2 -0
  226. package/dist/tools/descriptor.js.map +1 -0
  227. package/dist/tools/diagnostic-tools.d.ts +3 -0
  228. package/dist/tools/diagnostic-tools.d.ts.map +1 -0
  229. package/dist/tools/diagnostic-tools.js +128 -0
  230. package/dist/tools/diagnostic-tools.js.map +1 -0
  231. package/dist/tools/gateway-tools.d.ts +6 -0
  232. package/dist/tools/gateway-tools.d.ts.map +1 -0
  233. package/dist/tools/gateway-tools.js +381 -0
  234. package/dist/tools/gateway-tools.js.map +1 -0
  235. package/dist/tools/hash-tools.d.ts +5 -0
  236. package/dist/tools/hash-tools.d.ts.map +1 -0
  237. package/dist/tools/hash-tools.js +238 -0
  238. package/dist/tools/hash-tools.js.map +1 -0
  239. package/dist/tools/knowledge-tools.d.ts +7 -0
  240. package/dist/tools/knowledge-tools.d.ts.map +1 -0
  241. package/dist/tools/knowledge-tools.js +247 -0
  242. package/dist/tools/knowledge-tools.js.map +1 -0
  243. package/dist/tools/onboarding-checklist.d.ts +3 -0
  244. package/dist/tools/onboarding-checklist.d.ts.map +1 -0
  245. package/dist/tools/onboarding-checklist.js +141 -0
  246. package/dist/tools/onboarding-checklist.js.map +1 -0
  247. package/dist/tools/register.d.ts +60 -0
  248. package/dist/tools/register.d.ts.map +1 -0
  249. package/dist/tools/register.js +145 -0
  250. package/dist/tools/register.js.map +1 -0
  251. package/dist/tools/tool-kit.d.ts +88 -0
  252. package/dist/tools/tool-kit.d.ts.map +1 -0
  253. package/dist/tools/tool-kit.js +297 -0
  254. package/dist/tools/tool-kit.js.map +1 -0
  255. package/dist/validation/payload-validator.d.ts +29 -0
  256. package/dist/validation/payload-validator.d.ts.map +1 -0
  257. package/dist/validation/payload-validator.js +79 -0
  258. package/dist/validation/payload-validator.js.map +1 -0
  259. package/dist/validation/rules/amount.d.ts +3 -0
  260. package/dist/validation/rules/amount.d.ts.map +1 -0
  261. package/dist/validation/rules/amount.js +77 -0
  262. package/dist/validation/rules/amount.js.map +1 -0
  263. package/dist/validation/rules/bill-reference.d.ts +10 -0
  264. package/dist/validation/rules/bill-reference.d.ts.map +1 -0
  265. package/dist/validation/rules/bill-reference.js +34 -0
  266. package/dist/validation/rules/bill-reference.js.map +1 -0
  267. package/dist/validation/rules/cnic.d.ts +3 -0
  268. package/dist/validation/rules/cnic.d.ts.map +1 -0
  269. package/dist/validation/rules/cnic.js +42 -0
  270. package/dist/validation/rules/cnic.js.map +1 -0
  271. package/dist/validation/rules/constants.d.ts +9 -0
  272. package/dist/validation/rules/constants.d.ts.map +1 -0
  273. package/dist/validation/rules/constants.js +28 -0
  274. package/dist/validation/rules/constants.js.map +1 -0
  275. package/dist/validation/rules/constraints.d.ts +3 -0
  276. package/dist/validation/rules/constraints.d.ts.map +1 -0
  277. package/dist/validation/rules/constraints.js +113 -0
  278. package/dist/validation/rules/constraints.js.map +1 -0
  279. package/dist/validation/rules/datetime.d.ts +3 -0
  280. package/dist/validation/rules/datetime.d.ts.map +1 -0
  281. package/dist/validation/rules/datetime.js +49 -0
  282. package/dist/validation/rules/datetime.js.map +1 -0
  283. package/dist/validation/rules/empty-string.d.ts +13 -0
  284. package/dist/validation/rules/empty-string.d.ts.map +1 -0
  285. package/dist/validation/rules/empty-string.js +32 -0
  286. package/dist/validation/rules/empty-string.js.map +1 -0
  287. package/dist/validation/rules/expiry.d.ts +3 -0
  288. package/dist/validation/rules/expiry.d.ts.map +1 -0
  289. package/dist/validation/rules/expiry.js +52 -0
  290. package/dist/validation/rules/expiry.js.map +1 -0
  291. package/dist/validation/rules/msisdn.d.ts +3 -0
  292. package/dist/validation/rules/msisdn.d.ts.map +1 -0
  293. package/dist/validation/rules/msisdn.js +45 -0
  294. package/dist/validation/rules/msisdn.js.map +1 -0
  295. package/dist/validation/rules/presence.d.ts +3 -0
  296. package/dist/validation/rules/presence.d.ts.map +1 -0
  297. package/dist/validation/rules/presence.js +90 -0
  298. package/dist/validation/rules/presence.js.map +1 -0
  299. package/dist/validation/rules/return-url.d.ts +14 -0
  300. package/dist/validation/rules/return-url.d.ts.map +1 -0
  301. package/dist/validation/rules/return-url.js +58 -0
  302. package/dist/validation/rules/return-url.js.map +1 -0
  303. package/dist/validation/rules/tool-argument.d.ts +16 -0
  304. package/dist/validation/rules/tool-argument.d.ts.map +1 -0
  305. package/dist/validation/rules/tool-argument.js +38 -0
  306. package/dist/validation/rules/tool-argument.js.map +1 -0
  307. package/dist/validation/rules/txn-ref.d.ts +3 -0
  308. package/dist/validation/rules/txn-ref.d.ts.map +1 -0
  309. package/dist/validation/rules/txn-ref.js +47 -0
  310. package/dist/validation/rules/txn-ref.js.map +1 -0
  311. package/dist/validation/rules/unknown-fields.d.ts +10 -0
  312. package/dist/validation/rules/unknown-fields.d.ts.map +1 -0
  313. package/dist/validation/rules/unknown-fields.js +29 -0
  314. package/dist/validation/rules/unknown-fields.js.map +1 -0
  315. package/dist/validation/types.d.ts +36 -0
  316. package/dist/validation/types.d.ts.map +1 -0
  317. package/dist/validation/types.js +12 -0
  318. package/dist/validation/types.js.map +1 -0
  319. package/dist/version.d.ts +23 -0
  320. package/dist/version.d.ts.map +1 -0
  321. package/dist/version.js +23 -0
  322. package/dist/version.js.map +1 -0
  323. package/knowledge/diagnostics/symptoms.json +321 -0
  324. package/knowledge/docs/bnpl-guide.md +77 -0
  325. package/knowledge/docs/card-page-redirection.md +67 -0
  326. package/knowledge/docs/card-refund.md +91 -0
  327. package/knowledge/docs/hmac-sha256-calculation.md +72 -0
  328. package/knowledge/docs/index.json +189 -0
  329. package/knowledge/docs/ipn-implementation.md +89 -0
  330. package/knowledge/docs/mwallet-recurring.md +117 -0
  331. package/knowledge/docs/mwallet-refund.md +65 -0
  332. package/knowledge/docs/mwallet-rest-v1-1.md +126 -0
  333. package/knowledge/docs/mwallet-rest-v2-0-cnic.md +113 -0
  334. package/knowledge/docs/portal-guide.md +45 -0
  335. package/knowledge/docs/shopify-guide.md +74 -0
  336. package/knowledge/docs/status-inquiry-2025-26.md +32 -0
  337. package/knowledge/docs/status-inquiry.md +111 -0
  338. package/knowledge/docs/wordpress-guide.md +49 -0
  339. package/knowledge/flow.schema.json +390 -0
  340. package/knowledge/flows/bnpl-page-redirection-v1.1.json +211 -0
  341. package/knowledge/flows/card-page-redirection-v1.1.json +211 -0
  342. package/knowledge/flows/mwallet-rest-v1.1.json +187 -0
  343. package/knowledge/flows/mwallet-rest-v2.0-cnic.json +197 -0
  344. package/knowledge/flows/mwallet-token-pay-v4.0.json +130 -0
  345. package/knowledge/flows/refund-bnpl.json +105 -0
  346. package/knowledge/flows/refund-card-v1.1.json +112 -0
  347. package/knowledge/flows/refund-card-v2.0.json +121 -0
  348. package/knowledge/flows/refund-mwallet-v1.1.json +106 -0
  349. package/knowledge/flows/status-inquiry-v1.1.json +102 -0
  350. package/knowledge/flows/status-inquiry-v2.0.json +103 -0
  351. package/knowledge/flows/token-delete-v1.json +85 -0
  352. package/knowledge/flows/token-inquiry-v1.json +85 -0
  353. package/knowledge/flows/wallet-linking-portal.json +103 -0
  354. package/knowledge/templates/node/checkout-redirect.tmpl +166 -0
  355. package/knowledge/templates/node/ipn-handler.tmpl +108 -0
  356. package/knowledge/templates/node/rest-client.tmpl +197 -0
  357. package/knowledge/templates/node/wallet-linking.tmpl +147 -0
  358. package/knowledge/templates/php/checkout-redirect.tmpl +149 -0
  359. package/knowledge/templates/php/ipn-handler.tmpl +105 -0
  360. package/knowledge/templates/php/rest-client.tmpl +191 -0
  361. package/knowledge/templates/php/wallet-linking.tmpl +137 -0
  362. package/knowledge/templates/python/checkout-redirect.tmpl +148 -0
  363. package/knowledge/templates/python/ipn-handler.tmpl +110 -0
  364. package/knowledge/templates/python/rest-client.tmpl +179 -0
  365. package/knowledge/templates/python/wallet-linking.tmpl +133 -0
  366. package/package.json +84 -0
@@ -0,0 +1,77 @@
1
+ # Buy Now Pay Later (BNPL)
2
+
3
+ Source: `Page Redirection v1.1 template for (BNPL)_2026.pdf`, version 2026.
4
+
5
+ ## Introduction {#introduction}
6
+
7
+ Integrates JazzCash Buy Now Pay Later into a website or mobile application using BNPL page redirection. The request is structurally identical to card page redirection; only `pp_TxnType` differs.
8
+
9
+ > **Use production credentials for BNPL testing.** This is stated explicitly in the guide and is unlike every other flow, which is tested in sandbox. Treat every BNPL test as a live transaction: use the smallest possible amount, expect a real debit, and refund it afterwards.
10
+
11
+ ## Endpoint {#endpoint}
12
+
13
+ Form action, identical for both environments:
14
+
15
+ ```
16
+ https://onlinepayments.jazzcash.com.pk/payment-orchestrator/CustomerPortal/transactionmanagement/merchantform
17
+ ```
18
+
19
+ ## Request parameters {#request-parameters}
20
+
21
+ Identical to card page redirection, except:
22
+
23
+ - `pp_TxnType` is `BNPL` rather than `MPAY`.
24
+ - `ppmpf_1` through `ppmpf_5` are all marked "leave it empty"; the card guide marks `ppmpf_3`–`ppmpf_5` as optional.
25
+
26
+ `pp_Version` `1.1`, `pp_TxnType` `BNPL`, `pp_Language` `EN`, `pp_MerchantID`, `pp_Password`, `pp_TxnRefNo`, `pp_Amount`, `pp_TxnCurrency` `PKR`, `pp_TxnDateTime`, `pp_BillReference`, `pp_Description`, `pp_TxnExpiryDateTime`, `pp_ReturnURL`, `pp_SubMerchantID` `""`, `pp_BankID` `""`, `pp_ProductID` `""`, `ppmpf_1`–`ppmpf_5` `""`, plus `pp_SecureHash`.
27
+
28
+ ## Important notes {#important-notes}
29
+
30
+ - `pp_TxnRefNo` must be unique for every transaction.
31
+ - `pp_Amount` is in minor units: multiply by 100.
32
+ - `pp_TxnDateTime` and `pp_TxnExpiryDateTime` are `YYYYMMDDHHMMSS` in Pakistan Standard Time, the expiry being one day later.
33
+ - `pp_ReturnURL` must match the registered value exactly; it is part of merchant authentication.
34
+ - All empty fields must remain as `""`.
35
+
36
+ ## BNPL Refund API {#bnpl-refund-api}
37
+
38
+ Endpoint, identical for both environments:
39
+
40
+ ```
41
+ https://onlinepayments.jazzcash.com.pk/payment-orchestrator/api/v1/rest/payments/mpgs/authorize/refund
42
+ ```
43
+
44
+ This is the same URL as Card Refund v1.1, but the documented payload differs: the BNPL sample omits `pp_MerchantMPIN`, which the card refund guide marks mandatory.
45
+
46
+ Sample request:
47
+
48
+ ```json
49
+ {
50
+ "pp_TxnRefNo": "T20260114153733",
51
+ "pp_MerchantID": "{Merchant ID}",
52
+ "pp_Password": "{Password}",
53
+ "pp_SecureHash": "fde479ead7b9fdf231f4c992a62ac4413914f05a61cabf3f33dd0c90fcb52030",
54
+ "pp_Amount": "100",
55
+ "pp_TxnCurrency": "PKR"
56
+ }
57
+ ```
58
+
59
+ Sample response — note the **unprefixed** field names:
60
+
61
+ ```json
62
+ {
63
+ "ResponseCode": "000",
64
+ "ResponseMessage": "Thank you for using JazzCash. Your transaction was processed successfully.",
65
+ "RefundAmount": "100",
66
+ "TotalRefundAmount": "100",
67
+ "SecureHash": "20B6593DFC995F98A54EC1B397C150085A2CC53DDC6751B72C6B4E927977CB35"
68
+ }
69
+ ```
70
+
71
+ ## Common failures {#common-failures}
72
+
73
+ | Symptom | Cause | Fix |
74
+ | --- | --- | --- |
75
+ | Sandbox credentials rejected | BNPL is tested with production credentials | Use production credentials and the smallest possible amount |
76
+ | Response hash never verifies | Code looks for `pp_SecureHash` | BNPL refund responses return a bare `SecureHash` |
77
+ | Refund rejected as missing a field | Card refund payload assumed | The BNPL sample omits `pp_MerchantMPIN`; add it only if the gateway demands it, and report the conflict |
@@ -0,0 +1,67 @@
1
+ # Card Payment — Page Redirection / Checkout v1.1
2
+
3
+ Source: `Page Redirection v1.1 template for (Card Payments)_2026.pdf`, version 2026.
4
+
5
+ ## Introduction {#introduction}
6
+
7
+ Integrates JazzCash card payments into a website or mobile application using hosted checkout. The merchant renders a signed HTML form; the customer completes payment on the JazzCash landing page; the result is posted back to the registered Return URL. For a mobile application, the same redirection code is used inside a web view.
8
+
9
+ The landing page also offers mobile account and voucher payment, so a single integration covers three payment methods.
10
+
11
+ ## Creating a sandbox account {#create-a-sandbox-account}
12
+
13
+ 1. Sign up at <https://onlinepayments.jazzcash.com.pk/sandbox-frontend/>.
14
+ 2. Share your Merchant ID with JazzCash so the team can enable the payment options for you. Until they do, the payment method will not appear.
15
+ 3. In the sandbox portal, go to **Integration → Credentials** and record the Merchant ID, Password and Integrity Salt.
16
+ 4. Enter your **Return URL / Callback URL** in the same screen.
17
+ 5. If you are using instant payment notifications, enter your **IPN URL** as well.
18
+
19
+ ## Endpoint {#endpoint}
20
+
21
+ Form action, identical for both environments:
22
+
23
+ ```
24
+ https://onlinepayments.jazzcash.com.pk/payment-orchestrator/CustomerPortal/transactionmanagement/merchantform
25
+ ```
26
+
27
+ Because the URL does not distinguish sandbox from production, the environment is determined entirely by which credentials you post with.
28
+
29
+ ## Request parameters {#request-parameters}
30
+
31
+ `pp_Version` `1.1`, `pp_TxnType` `MPAY`, `pp_Language` `EN`, `pp_MerchantID`, `pp_Password`, `pp_TxnRefNo`, `pp_Amount`, `pp_TxnCurrency` `PKR`, `pp_TxnDateTime`, `pp_BillReference`, `pp_Description`, `pp_TxnExpiryDateTime`, `pp_ReturnURL`, `pp_SubMerchantID` `""`, `pp_BankID` `""`, `pp_ProductID` `""`, `ppmpf_1` `""`, `ppmpf_2` `""`, `ppmpf_3`–`ppmpf_5` optional, plus `pp_SecureHash`.
32
+
33
+ `pp_TxnType` is the only difference from the BNPL flow, which uses `BNPL`.
34
+
35
+ ## Important notes {#important-notes}
36
+
37
+ - **`pp_TxnRefNo`** is a unique identifier and must be a unique value for every transaction.
38
+ - **`pp_Amount`** is mandatory. The last two digits are treated as decimals, so multiply the product amount by 100 (2 × 100 = 200).
39
+ - **`pp_TxnDateTime`** is `YYYYMMDDHHMMSS` in Pakistan Standard Time.
40
+ - **`pp_TxnExpiryDateTime`** is `YYYYMMDDHHMMSS` in Pakistan Standard Time, one day after the current date.
41
+ - **`pp_ReturnURL`** is mandatory and must be shared with JazzCash before use, because it becomes part of your merchant profile. It must be identical in every request: it is part of merchant authentication, and any difference fails validation.
42
+ - Keep all mandatory parameters in every request.
43
+ - All empty fields must remain as `""`.
44
+ - Generate `pp_SecureHash` per the JazzCash hashing guidelines before sending the request.
45
+
46
+ ## Testing evidence required {#testing}
47
+
48
+ Perform test transactions and capture screenshots for each payment method — mobile account, voucher payment, and credit/debit card. For each method, supply screenshots of:
49
+
50
+ - the merchant checkout page;
51
+ - the JazzCash landing page;
52
+ - payment method selection;
53
+ - the payment step;
54
+ - the payment response received on the merchant Callback URL;
55
+ - the order status in the merchant admin panel.
56
+
57
+ Paste the screenshots into the supplied template document and reply on the same email thread.
58
+
59
+ ## Common failures {#common-failures}
60
+
61
+ | Symptom | Cause | Fix |
62
+ | --- | --- | --- |
63
+ | Validation failure with correct-looking data | `pp_ReturnURL` differs from the registered value, even by a trailing slash | Send the registered URL byte for byte |
64
+ | Payment method missing from the landing page | JazzCash has not enabled it for your Merchant ID | Send your Merchant ID to JazzCash and ask for the method to be enabled |
65
+ | Duplicate transaction rejected | `pp_TxnRefNo` reused | Append a timestamp with millisecond precision |
66
+ | Customer charged the wrong amount | `pp_Amount` sent in major units | Multiply by 100 |
67
+ | Form submits but the hash is rejected | Values HTML-escaped after hashing, or not escaped at all | Escape when rendering, hash the unescaped values you intend to send |
@@ -0,0 +1,91 @@
1
+ # Card Refund API
2
+
3
+ Source: `Card Refund API (2026).pdf`, version 2026.
4
+
5
+ ## Introduction {#introduction}
6
+
7
+ Refunds a completed card transaction, in whole or in part. Two versions are documented; both are live.
8
+
9
+ The Merchant MPIN must already be **saved in the merchant portal** before a refund will succeed, in addition to being sent in the request.
10
+
11
+ ## REST-based Card Refund API v1.1 {#rest-based-card-refund-api-v1-1}
12
+
13
+ Endpoint, identical for both environments:
14
+
15
+ ```
16
+ https://onlinepayments.jazzcash.com.pk/payment-orchestrator/api/v1/rest/payments/mpgs/authorize/refund
17
+ ```
18
+
19
+ This is the same URL used by the BNPL refund, which documents a different payload.
20
+
21
+ Request:
22
+
23
+ ```json
24
+ {
25
+ "pp_TxnRefNo": "T20251224170612",
26
+ "pp_Amount": "100",
27
+ "pp_TxnCurrency": "PKR",
28
+ "pp_MerchantID": "YOUR MERCHANT ID",
29
+ "pp_Password": "YOUR PASSWORD",
30
+ "pp_MerchantMPIN": "YOUR MERCHANT MPIN",
31
+ "pp_SecureHash": "c2537a63bb3314b53232603a6f56c394f96f7ce8e28c62ec8c6ab9da83367db0"
32
+ }
33
+ ```
34
+
35
+ Response:
36
+
37
+ ```json
38
+ {
39
+ "ResponseCode": "000",
40
+ "ResponseMessage": "Thank you for using JazzCash. Your transaction was processed successfully.",
41
+ "RefundAmount": "100",
42
+ "TotalRefundAmount": "100",
43
+ "SecureHash": "20B6593DFC995F98A54EC1B397C150085A2CC53DDC6751B72C6B4E927977CB35"
44
+ }
45
+ ```
46
+
47
+ ## REST-based Card Refund API v2.0 {#rest-based-card-refund-api-v2-0}
48
+
49
+ Endpoint, identical for both environments:
50
+
51
+ ```
52
+ https://onlinepayments.jazzcash.com.pk/payment-orchestrator/api/v1/rest/payments/mpgs/v2.0/authorize/refund
53
+ ```
54
+
55
+ Note that the version marker is in the path segment `v2.0`, while the API prefix stays `api/v1`.
56
+
57
+ The request is identical to v1.1. The response adds acquirer detail useful for reconciliation:
58
+
59
+ ```json
60
+ {
61
+ "ResponseCode": "000",
62
+ "ResponseMessage": "Thank you for using JazzCash. Your transaction was processed successfully.",
63
+ "RefundAmount": "100",
64
+ "TotalRefundAmount": "100",
65
+ "TxnRefNo": "T20251224174341",
66
+ "MerchantID": "YOUR MERCHANT ID",
67
+ "RetrievalReferenceNo": "202512241751151549494723",
68
+ "Stan": "203190",
69
+ "Receipt": "535812203190",
70
+ "Terminal": "80520144",
71
+ "SecureHash": "E3F8DD09E8E6E6CAF348E27AC42BCF1A2FFE884DB86C588675F541425B9FB79F7"
72
+ }
73
+ ```
74
+
75
+ Prefer v2.0: `TotalRefundAmount` plus the acquirer references let you reconcile partial refunds without a separate lookup.
76
+
77
+ ## Unprefixed response fields {#unprefixed-response-fields}
78
+
79
+ Card refund responses use **`ResponseCode`, `ResponseMessage` and `SecureHash`** — with no `pp_` prefix. Every other documented JazzCash response prefixes them. Code that looks only for `pp_SecureHash` will silently skip verification of a refund response.
80
+
81
+ `RefundAmount` is the amount refunded by this call; `TotalRefundAmount` is the cumulative total refunded against the original transaction. Compare the latter against the original amount to know whether a transaction is fully refunded.
82
+
83
+ ## Common failures {#common-failures}
84
+
85
+ | Symptom | Cause | Fix |
86
+ | --- | --- | --- |
87
+ | Refund rejected | MPIN not saved in the merchant portal | Save it in the portal, then retry |
88
+ | Response hash never verifies | Reading `pp_SecureHash` | Read the bare `SecureHash` |
89
+ | Refund appears to succeed but nothing returns | Refunding an incomplete transaction | Confirm the original completed with Status Inquiry first |
90
+ | Over-refund accepted then reversed | Not tracking `TotalRefundAmount` | Compare the cumulative total against the original amount before refunding |
91
+ | Amount mismatch | Refund amount sent in major units | `pp_Amount` is in minor units here too |
@@ -0,0 +1,72 @@
1
+ # HMAC-SHA256 (pp_SecureHash) Calculation
2
+
3
+ Source: `How is HMAC-SHA256 calculated (2026).pdf`, version 2026.
4
+
5
+ ## The algorithm {#how-is-hmac-sha256-calculated}
6
+
7
+ The secure hash is computed the same way for every JazzCash flow.
8
+
9
+ 1. Take **all non-empty fields** from the request.
10
+ 2. Sort by **parameter name**, ascending alphabetical (ASCII) order.
11
+ 3. Concatenate the **values** — not the names — joining them with `&`.
12
+ 4. **Prepend** the Integrity Salt (also called the Hash Key), separated by `&`.
13
+ 5. Hash the result with **HMAC-SHA256**, using the Integrity Salt itself as the secret key.
14
+
15
+ The salt therefore appears twice: once as the first element of the message, and once as the HMAC key.
16
+
17
+ ## Worked example {#sorted-hash-array}
18
+
19
+ With Integrity Salt `3vv9wu3a18` and these parameters:
20
+
21
+ ```json
22
+ {
23
+ "pp_Amount": "25000",
24
+ "pp_MerchantID": "MC25041",
25
+ "pp_MerchantMPIN": "1234",
26
+ "pp_Password": "sz1v4agvyf",
27
+ "pp_TxnCurrency": "PKR",
28
+ "pp_TxnRefNo": "T20220518150213"
29
+ }
30
+ ```
31
+
32
+ Sorted by name and joined by `&`, the values are:
33
+
34
+ ```
35
+ 25000&MC25041&1234&sz1v4agvyf&PKR&T20220518150213
36
+ ```
37
+
38
+ After prepending the Integrity Salt:
39
+
40
+ ```
41
+ 3vv9wu3a18&25000&MC25041&1234&sz1v4agvyf&PKR&T20220518150213
42
+ ```
43
+
44
+ That string is then hashed with HMAC-SHA256 using the key `3vv9wu3a18`.
45
+
46
+ ## Rules that are easy to miss {#rules-that-are-easy-to-miss}
47
+
48
+ - **Empty fields are sent but not hashed.** A parameter you are told to "leave empty" must still appear in the request as `""`. It simply does not contribute a value to the hash string.
49
+ - **`pp_SecureHash` is never part of its own input.** Remove it from the parameter set before hashing.
50
+ - **Sorting is by name; concatenation is of values.** The names never appear in the hash string.
51
+ - **Case of the output does not matter.** PHP's `hash_hmac` returns lowercase hex; JazzCash response samples show uppercase. Compare case-insensitively.
52
+ - **Uppercase letters sort before lowercase** in ASCII, and `_` (0x5F) sorts before `m` (0x6D), so every `pp_*` field precedes every `ppmpf_*` field.
53
+
54
+ ## Common failures {#common-failures}
55
+
56
+ | Symptom | Cause | Fix |
57
+ | --- | --- | --- |
58
+ | Hash mismatch on every request | Salt appended instead of prepended | Build `salt & v1 & v2 …` |
59
+ | Hash mismatch on every request | Salt used only as the HMAC key | Prepend it to the message as well |
60
+ | Hash mismatch when some fields are blank | Empty fields included in the hash string | Skip empty values when hashing, but still send them |
61
+ | Hash mismatch on retries only | A stale `pp_SecureHash` left in the payload and hashed | Exclude `pp_SecureHash` before hashing |
62
+ | Works in one language, fails in another | Locale-sensitive sorting | Sort by raw ASCII, never with a locale-aware comparator |
63
+ | Intermittent mismatch | Payload mutated after the hash was computed | Hash last, from the exact map you transmit |
64
+ | Mismatch only when an amount is zero-like | PHP's loose `$value != ""` drops integer `0` | Compare with `(string)$value !== ''` |
65
+
66
+ ## Divergences from the official PHP sample {#php-sample-divergences}
67
+
68
+ The sample published in the redirection guides has two defects worth correcting in your own code:
69
+
70
+ - `if ($value != null && $value != "")` evaluates false for integer `0`, silently dropping that field.
71
+ Use `if ($value !== null && (string)$value !== '')`.
72
+ - `ksort($Params)` uses `SORT_REGULAR`. Use `ksort($Params, SORT_STRING)` so ordering is a plain string comparison, as the specification requires.
@@ -0,0 +1,189 @@
1
+ {
2
+ "corpusVersion": "2026",
3
+ "note": "Document-level metadata. Sections are derived from the '## Title {#anchor}' headings in each markdown file, so the two cannot drift.",
4
+ "documents": [
5
+ {
6
+ "docId": "hmac-sha256-calculation",
7
+ "title": "HMAC-SHA256 (pp_SecureHash) Calculation",
8
+ "sourcePdf": "docs/integration_documents/How is HMAC-SHA256 calculated (2026).pdf",
9
+ "version": "2026",
10
+ "flowIds": [],
11
+ "keywords": [
12
+ "hash",
13
+ "secure hash",
14
+ "pp_SecureHash",
15
+ "hmac",
16
+ "sha256",
17
+ "integrity salt",
18
+ "hash key",
19
+ "mismatch",
20
+ "sorting",
21
+ "signature"
22
+ ]
23
+ },
24
+ {
25
+ "docId": "card-page-redirection",
26
+ "title": "Card Payment — Page Redirection / Checkout v1.1",
27
+ "sourcePdf": "docs/integration_documents/Page Redirection v1.1 template for (Card Payments)_2026.pdf",
28
+ "version": "2026",
29
+ "flowIds": ["card-page-redirection-v1.1"],
30
+ "keywords": [
31
+ "card",
32
+ "checkout",
33
+ "hosted page",
34
+ "redirection",
35
+ "MPAY",
36
+ "landing page",
37
+ "return url",
38
+ "voucher",
39
+ "credit",
40
+ "debit"
41
+ ]
42
+ },
43
+ {
44
+ "docId": "bnpl-guide",
45
+ "title": "Buy Now Pay Later (BNPL)",
46
+ "sourcePdf": "docs/integration_documents/Page Redirection v1.1 template for (BNPL)_2026.pdf",
47
+ "version": "2026",
48
+ "flowIds": ["bnpl-page-redirection-v1.1", "refund-bnpl"],
49
+ "keywords": ["bnpl", "buy now pay later", "instalments", "credit", "redirection", "refund"]
50
+ },
51
+ {
52
+ "docId": "mwallet-rest-v1-1",
53
+ "title": "MWallet REST API v1.1 (without CNIC)",
54
+ "sourcePdf": "docs/integration_documents/MWallet API v1.1 (Without CNIC)_Merchant Guide_(2026).pdf",
55
+ "version": "2026",
56
+ "flowIds": ["mwallet-rest-v1.1"],
57
+ "keywords": [
58
+ "mwallet",
59
+ "mobile wallet",
60
+ "mobile account",
61
+ "rest",
62
+ "v1.1",
63
+ "ppmpf_1",
64
+ "without cnic",
65
+ "direct debit"
66
+ ]
67
+ },
68
+ {
69
+ "docId": "mwallet-rest-v2-0-cnic",
70
+ "title": "MWallet REST API v2.0 (with CNIC)",
71
+ "sourcePdf": "docs/integration_documents/MWallet API V.2.0 (With CNIC)_Merchant Guide_(2026).pdf",
72
+ "version": "2026",
73
+ "flowIds": ["mwallet-rest-v2.0-cnic"],
74
+ "keywords": ["mwallet", "mobile wallet", "cnic", "rest", "v2.0", "pp_MobileNumber", "identity"]
75
+ },
76
+ {
77
+ "docId": "mwallet-recurring",
78
+ "title": "MWallet Recurring Payments — Linking, Token Payment, Token Inquiry, Token Delete",
79
+ "sourcePdf": "docs/integration_documents/MWallet Recurring Payments (2026).pdf",
80
+ "version": "2026",
81
+ "flowIds": ["wallet-linking-portal", "mwallet-token-pay-v4.0", "token-inquiry-v1", "token-delete-v1"],
82
+ "keywords": [
83
+ "recurring",
84
+ "subscription",
85
+ "wallet linking",
86
+ "payment token",
87
+ "token",
88
+ "mpin",
89
+ "v4.0",
90
+ "pp_RequestID",
91
+ "unlink"
92
+ ]
93
+ },
94
+ {
95
+ "docId": "status-inquiry",
96
+ "title": "Status Inquiry API",
97
+ "sourcePdf": "docs/integration_documents/Status Inquiry Guide (2026).pdf",
98
+ "version": "2026",
99
+ "flowIds": ["status-inquiry-v1.1", "status-inquiry-v2.0"],
100
+ "keywords": [
101
+ "status",
102
+ "inquiry",
103
+ "enquiry",
104
+ "pending",
105
+ "reconciliation",
106
+ "121",
107
+ "pp_PaymentResponseCode",
108
+ "missing transaction"
109
+ ]
110
+ },
111
+ {
112
+ "docId": "status-inquiry-2025-26",
113
+ "title": "Status Inquiry Guide (2025-26 edition — superseded)",
114
+ "sourcePdf": "docs/integration_documents/Status Inquiry Guide_Merchants_Latest_2025-26.pdf",
115
+ "version": "2025-26",
116
+ "flowIds": ["status-inquiry-v1.1", "status-inquiry-v2.0"],
117
+ "keywords": ["status", "inquiry", "superseded", "older edition", "contradiction", "copy-paste"]
118
+ },
119
+ {
120
+ "docId": "ipn-implementation",
121
+ "title": "IPN (Instant Payment Notification) Implementation",
122
+ "sourcePdf": "docs/integration_documents/IPN Guide for Merchants (REST API)_2026.pdf",
123
+ "version": "2026",
124
+ "flowIds": [],
125
+ "keywords": [
126
+ "ipn",
127
+ "instant payment notification",
128
+ "webhook",
129
+ "callback",
130
+ "notification",
131
+ "retry",
132
+ "idempotent",
133
+ "listener",
134
+ "60 seconds"
135
+ ]
136
+ },
137
+ {
138
+ "docId": "card-refund",
139
+ "title": "Card Refund API",
140
+ "sourcePdf": "docs/integration_documents/Card Refund API (2026).pdf",
141
+ "version": "2026",
142
+ "flowIds": ["refund-card-v1.1", "refund-card-v2.0"],
143
+ "keywords": ["refund", "card", "reversal", "mpin", "partial refund", "TotalRefundAmount", "mpgs"]
144
+ },
145
+ {
146
+ "docId": "mwallet-refund",
147
+ "title": "Mobile Wallet Refund API v1.1",
148
+ "sourcePdf": "docs/integration_documents/Mobile Wallet Refund API (2026).pdf",
149
+ "version": "2026",
150
+ "flowIds": ["refund-mwallet-v1.1"],
151
+ "keywords": ["refund", "mwallet", "mobile wallet", "reversal", "mpin", "partial refund"]
152
+ },
153
+ {
154
+ "docId": "portal-guide",
155
+ "title": "JazzCash Merchant Portal",
156
+ "sourcePdf": "docs/integration_documents/Portal Guide 2026.pdf",
157
+ "version": "2026",
158
+ "flowIds": [],
159
+ "keywords": [
160
+ "portal",
161
+ "dashboard",
162
+ "credentials",
163
+ "integrity salt",
164
+ "login",
165
+ "otp",
166
+ "role management",
167
+ "transaction detail report",
168
+ "tdr",
169
+ "reports"
170
+ ]
171
+ },
172
+ {
173
+ "docId": "shopify-guide",
174
+ "title": "Shopify Integration",
175
+ "sourcePdf": "docs/integration_documents/Shopify Guide.pdf",
176
+ "version": "2026",
177
+ "flowIds": [],
178
+ "keywords": ["shopify", "app", "plugin", "ecommerce", "migration", "old app", "storefront"]
179
+ },
180
+ {
181
+ "docId": "wordpress-guide",
182
+ "title": "WordPress / WooCommerce Integration",
183
+ "sourcePdf": "docs/integration_documents/WordPress Integration Guide (2026).pdf",
184
+ "version": "2026",
185
+ "flowIds": [],
186
+ "keywords": ["wordpress", "woocommerce", "plugin", "wp", "ecommerce", "wc-api", "jazzcash_ipn_v2"]
187
+ }
188
+ ]
189
+ }
@@ -0,0 +1,89 @@
1
+ # IPN (Instant Payment Notification) Implementation
2
+
3
+ Source: `IPN Guide for Merchants (REST API)_2026.pdf`, version 2026.
4
+
5
+ ## Overview {#overview}
6
+
7
+ JazzCash notifies merchants when a payment completes. After a transaction, the payment gateway posts the transaction status to a REST endpoint the merchant exposes.
8
+
9
+ IPN is a **mandatory** integration for the MWallet REST and recurring flows.
10
+
11
+ ## Retry behaviour {#retry-behaviour}
12
+
13
+ If the merchant returns a failed response, or if no response is received **within 60 seconds**, JazzCash retries **two more times**, with a short delay between attempts.
14
+
15
+ Two consequences for your handler:
16
+
17
+ - It must respond well inside 60 seconds. Acknowledge first, then do the slow work asynchronously.
18
+ - It must be **idempotent**. The same notification can legitimately arrive three times, and reprocessing it must not fulfil an order twice or double-count revenue.
19
+
20
+ ## Expected response from the merchant {#expected-ipn-response}
21
+
22
+ ```json
23
+ {
24
+ "pp_ResponseCode": "000",
25
+ "pp_ResponseMessage": "IPN received successfully",
26
+ "pp_SecureHash": "{{Your Generated Secure Hash}}"
27
+ }
28
+ ```
29
+
30
+ `000` here means "I received this notification", not "the payment succeeded".
31
+
32
+ ## Response codes inside the notification {#response-codes}
33
+
34
+ | Code | Meaning |
35
+ | --- | --- |
36
+ | `121` | Successful transaction |
37
+ | `199`, `999`, others | Failed transaction |
38
+
39
+ Note that in an **inbound IPN** the payment outcome arrives in `pp_ResponseCode`, whereas in a Status Inquiry response it arrives in `pp_PaymentResponseCode`. The same field name carries a different meaning depending on which direction the message travels.
40
+
41
+ ## Sample notification {#sample-notification}
42
+
43
+ ```json
44
+ {
45
+ "pp_Version": "2.0",
46
+ "pp_TxnType": "MWALLET",
47
+ "pp_BankID": "",
48
+ "pp_ProductID": null,
49
+ "pp_Password": "0123456789",
50
+ "pp_TxnRefNo": "T20240418145702",
51
+ "pp_TxnDateTime": "20240418145702",
52
+ "pp_ResponseCode": "121",
53
+ "pp_ResponseMessage": "Transaction has been marked confirmed by Merchant.",
54
+ "pp_AuthCode": "060935465981",
55
+ "pp_SettlementExpiry": null,
56
+ "pp_RetreivalReferenceNo": "240418718258",
57
+ "pp_SecureHash": "2B47BCF7825FA27FC8B522292BC8D226213FCCDA685FC68A67EC20B10836E5B7"
58
+ }
59
+ ```
60
+
61
+ The sample endpoint given in the guide is a `beeceptor.com` test URL. Register your own URL under **Integration → Credentials**.
62
+
63
+ ## Verifying the notification {#verifying-the-notification}
64
+
65
+ An IPN endpoint is a publicly reachable URL that marks orders as paid. Anyone can post to it.
66
+
67
+ **Always verify `pp_SecureHash` before acting on a notification.** Recompute it from the received fields using your Integrity Salt and compare case-insensitively. Reject anything that does not match.
68
+
69
+ Note that the notification contains `null` values (`pp_ProductID`, `pp_SettlementExpiry`) even though merchants are told never to send `null` in requests. Treat a `null` as empty when recomputing the hash.
70
+
71
+ ## Handler checklist {#handler-checklist}
72
+
73
+ - [ ] Verify `pp_SecureHash` before anything else.
74
+ - [ ] Look up the order by `pp_TxnRefNo`.
75
+ - [ ] Check the amount matches the order you recorded.
76
+ - [ ] If the order is already marked paid, return `000` and stop — the notification is a retry.
77
+ - [ ] Interpret `pp_ResponseCode`: `121` succeeded, `199`/`999` failed, anything else is unresolved.
78
+ - [ ] Respond with `000` within 60 seconds.
79
+ - [ ] Reconcile against the Status Inquiry API for any transaction where no IPN arrived.
80
+
81
+ ## Common failures {#common-failures}
82
+
83
+ | Symptom | Cause | Fix |
84
+ | --- | --- | --- |
85
+ | Orders fulfilled twice | Handler is not idempotent and JazzCash retried | Key on `pp_TxnRefNo` and ignore repeats |
86
+ | JazzCash reports IPN failures | Handler does slow work before responding | Acknowledge first, process asynchronously |
87
+ | Fraudulent "paid" orders | `pp_SecureHash` not verified | Verify before acting |
88
+ | No IPN ever arrives | IPN URL not registered, or unreachable from the internet | Register it under Integration → Credentials and confirm it is publicly reachable |
89
+ | Hash never matches | `null` values not normalised to empty | Treat `null` as `""` when recomputing |