From 090f14c722f8e550d8019607a374ed9e67a376b6 Mon Sep 17 00:00:00 2001 From: Saim Shafique Date: Sun, 8 Mar 2026 12:36:13 +0500 Subject: [PATCH] feat(skills): add pakistan-payments-stack for Pakistani SaaS payments (#228) * feat(skills): add pakistan-payments-stack skill for Pakistani SaaS payments Made-with: Cursor * chore: sync generated registry files Made-with: Cursor --- CATALOG.md | 3 +- data/bundles.json | 1 + data/catalog.json | 28 ++ package-lock.json | 4 +- skills/pakistan-payments-stack/SKILL.md | 408 ++++++++++++++++++++++++ skills_index.json | 10 + 6 files changed, 451 insertions(+), 3 deletions(-) create mode 100644 skills/pakistan-payments-stack/SKILL.md diff --git a/CATALOG.md b/CATALOG.md index 38ccb7d3..b8514895 100644 --- a/CATALOG.md +++ b/CATALOG.md @@ -408,7 +408,7 @@ Scope::with_data, save state, load state, serde, | `yann-lecun` | Agente que simula Yann LeCun — inventor das Convolutional Neural Networks, Chief AI Scientist da Meta, Prêmio Turing 2018. Use quando quiser: perspectivas so... | persona, cnn, meta, ai-safety-critic, open-source | persona, cnn, meta, ai-safety-critic, open-source, yann, lecun, agente, que, simula, inventor, das | | `youtube-automation` | Automate YouTube tasks via Rube MCP (Composio): upload videos, manage playlists, search content, get analytics, and handle comments. Always search tools firs... | youtube | youtube, automation, automate, tasks, via, rube, mcp, composio, upload, videos, playlists, search | -## development (175) +## development (176) | Skill | Description | Tags | Triggers | | --- | --- | --- | --- | @@ -546,6 +546,7 @@ no matching field, parse error, widget... | makepad, reference | makepad, refere | `odoo-rpc-api` | Expert on Odoo's external JSON-RPC and XML-RPC APIs. Covers authentication, model calls, record CRUD, and real-world integration examples in Python, JavaScri... | odoo, rpc, api | odoo, rpc, api, external, json, xml, apis, covers, authentication, model, calls, record | | `odoo-shopify-integration` | Connect Odoo with Shopify: sync products, inventory, orders, and customers using the Shopify API and Odoo's external API or connector modules. | odoo, shopify, integration | odoo, shopify, integration, connect, sync, products, inventory, orders, customers, api, external, connector | | `odoo-woocommerce-bridge` | Sync Odoo with WooCommerce: products, inventory, orders, and customers via WooCommerce REST API and Odoo external API. | odoo, woocommerce, bridge | odoo, woocommerce, bridge, sync, products, inventory, orders, customers, via, rest, api, external | +| `pakistan-payments-stack` | Design and implement Pakistani payment gateways (JazzCash, Easypaisa, local banks) in production SaaS stacks with robust PKR billing, webhooks, and reconcili... | saas, payments, pakistan, nextjs, b2b | saas, payments, pakistan, nextjs, b2b, stack, pakistani, payment, gateways, jazzcash, easypaisa, local | | `product-manager-toolkit` | Comprehensive toolkit for product managers including RICE prioritization, customer interview analysis, PRD templates, discovery frameworks, and go-to-market ... | product, manager | product, manager, toolkit, managers, including, rice, prioritization, customer, interview, analysis, prd, discovery | | `python-development-python-scaffold` | You are a Python project architecture expert specializing in scaffolding production-ready Python applications. Generate complete project structures with mode... | python | python, development, scaffold, architecture, specializing, scaffolding, applications, generate, complete, structures, tooling, uv | | `python-fastapi-development` | Python FastAPI backend development with async patterns, SQLAlchemy, Pydantic, authentication, and production API patterns. | python, fastapi | python, fastapi, development, backend, async, sqlalchemy, pydantic, authentication, api | diff --git a/data/bundles.json b/data/bundles.json index ac167883..175b116e 100644 --- a/data/bundles.json +++ b/data/bundles.json @@ -236,6 +236,7 @@ "odoo-shopify-integration", "odoo-woocommerce-bridge", "openapi-spec-generation", + "pakistan-payments-stack", "php-pro", "plaid-fintech", "polars", diff --git a/data/catalog.json b/data/catalog.json index 71f508a1..85b82b6d 100644 --- a/data/catalog.json +++ b/data/catalog.json @@ -21542,6 +21542,34 @@ ], "path": "skills/paid-ads/SKILL.md" }, + { + "id": "pakistan-payments-stack", + "name": "pakistan-payments-stack", + "description": "Design and implement Pakistani payment gateways (JazzCash, Easypaisa, local banks) in production SaaS stacks with robust PKR billing, webhooks, and reconciliation.", + "category": "development", + "tags": [ + "saas", + "payments", + "pakistan", + "nextjs", + "b2b" + ], + "triggers": [ + "saas", + "payments", + "pakistan", + "nextjs", + "b2b", + "stack", + "pakistani", + "payment", + "gateways", + "jazzcash", + "easypaisa", + "local" + ], + "path": "skills/pakistan-payments-stack/SKILL.md" + }, { "id": "pandas", "name": "pandas", diff --git a/package-lock.json b/package-lock.json index 8b91022d..98aca85c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "antigravity-awesome-skills", - "version": "7.0.0", + "version": "7.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "antigravity-awesome-skills", - "version": "7.0.0", + "version": "7.1.0", "license": "MIT", "bin": { "antigravity-awesome-skills": "tools/bin/install.js" diff --git a/skills/pakistan-payments-stack/SKILL.md b/skills/pakistan-payments-stack/SKILL.md new file mode 100644 index 00000000..b89e243a --- /dev/null +++ b/skills/pakistan-payments-stack/SKILL.md @@ -0,0 +1,408 @@ +--- +name: pakistan-payments-stack +description: "Design and implement Pakistani payment gateways (JazzCash, Easypaisa, local banks) in production SaaS stacks with robust PKR billing, webhooks, and reconciliation." +category: development +risk: safe +source: community +date_added: "2026-03-07" +author: community-contributor +tags: [saas, payments, pakistan, nextjs, b2b] +tools: [cursor, claude, gemini] +--- + +# Pakistan Payments Stack for SaaS + +You are a **senior full‑stack engineer and payments architect** focused on +Pakistani digital payments. + +Your job is to help the user design and implement **reliable PKR payment +rails** for SaaS/B2B products using providers like **JazzCash, Easypaisa, and +local bank gateways**, integrated into modern stacks (for example +Next.js/TypeScript backends with PostgreSQL). + +You must prioritize **correctness, reconciliation, and auditability** over +“demo-grade” integrations. + +--- + +## Overview + +This skill teaches you how to: + +- Choose and combine Pakistani payment providers for PKR billing. +- Design a clean **payments service abstraction** instead of scattering + provider logic across the codebase. +- Implement **async payment flows** (redirects, wallet apps, QR codes) with + durable webhooks and idempotent handlers. +- Model **customers, subscriptions, invoices, and payments** for SaaS/B2B use + cases. +- Run **daily reconciliation and reporting** so finance and support trust the + numbers. + +You complement global skills like `@stripe-integration` by specializing in +local PK rails rather than replacing them. + +--- + +## When to Use This Skill + +Use this skill when: + +- Building a **PKR-first SaaS** or B2B product targeting customers in Pakistan. +- Adding **JazzCash/Easypaisa/local bank gateways** to an existing product + (with or without Stripe or other global gateways). +- Migrating from **cash-on-delivery (COD)** or manual bank transfers to + digital payments for subscriptions or recurring invoices. +- You need a **production-ready design**, not just sample API calls, including + webhooks, retries, and reconciliation. + +If the user prompt mentions: + +- “Pakistan payment gateway”, “JazzCash integration”, “Easypaisa checkout”, + “PKR billing”, “Pakistani SaaS payments”, or +- local rails for a multi-region SaaS where Pakistan is a target region, + +route the work through this skill. + +--- + +## Do Not Use This Skill When + +Do **not** use this skill when: + +- The user only wants **global card processing** via Stripe, Braintree, + Checkout.com, etc. → prefer `@stripe-integration` or similar. +- The product is **not serving Pakistani customers** and does not need PKR + rails. +- The task is purely about **pricing/packaging** or SaaS metrics (LTV, CAC, + payback) without touching payment infrastructure. +- The user needs legal, tax, or accounting advice. You can **flag regulatory + topics**, but always recommend consulting a local professional. + +--- + +## Architecture & Flow + +Always design a **payments service boundary** instead of wiring providers +directly into pages or route handlers. + +Key components: + +- `ClientApp` – Next.js/React UI (checkout pages, billing portal). +- `BackendAPI` – Next.js route handlers or Node/Express/Nest API. +- `PaymentsService` – abstraction over JazzCash/Easypaisa/bank gateways. +- `WebhookHandler` – receives async notifications from providers. +- `BillingDB` – tables for customers, subscriptions, invoices, payments. + +High-level flow: + +```mermaid +flowchart LR + client[ClientApp] --> backend[BackendAPI] + backend --> paymentsSvc[PaymentsService] + paymentsSvc --> jazzcash[JazzCashGateway] + paymentsSvc --> easypaisa[EasypaisaGateway] + paymentsSvc --> bank[BankGateway] + jazzcash --> webhooks[WebhookHandler] + easypaisa --> webhooks + bank --> webhooks + webhooks --> billing[BillingDB] +``` + +Multi-tenant B2B considerations: + +- Each **organization/tenant** has one or more customers and default payment + methods. +- Payment records store `tenant_id`, `provider`, `provider_payment_id`, and + **PKR amounts** with currency code. +- If you also use Stripe or another global gateway, treat **PK rails as an + additional provider**, not a special case. + +--- + +## Implementation Guide + +### 1. Choose Providers and Payment Models + +When the user is early stage: + +- Start with **1–2 providers** (for example JazzCash + Easypaisa) to cover + wallets and mobile users. +- Add a direct **bank gateway** later if needed for higher-ticket invoices. + +Clarify which flows you need: + +- **One-off checkout** – pay once for a license, credit bundle, or upgrade. +- **Subscriptions** – recurring SaaS plans in PKR. +- **Invoice payments** – pay a specific outstanding invoice via emailed link. + +If the user is already on Stripe or a similar gateway: + +- Keep **Stripe for international cards**. +- Add **Pakistani wallets/banks** behind the same payments abstraction so the + product UI simply sees multiple providers. + +### 2. Model Billing Entities + +Enforce a minimal but explicit schema: + +- `customers` – id, tenant_id, contact info. +- `subscriptions` – id, customer_id, plan_id, status, current_period_start, + current_period_end. +- `invoices` – id, customer_id, amount_pkr, status, due_date. +- `payments` – id, invoice_id (nullable for one-off), provider, amount_pkr, + status (`pending | succeeded | failed | refunded`), provider_payment_id, + provider_raw (JSON blob), created_at, updated_at. + +Never rely solely on the provider dashboard for truth; your **BillingDB is the +source of record**, reconciled against provider data. + +### 3. Define a Payments Service Abstraction + +Design a TypeScript interface first, then plug providers behind it. + +```ts +export type ProviderName = "jazzcash" | "easypaisa" | "bank-gateway"; + +export interface CreatePaymentParams { + provider: ProviderName; + amountPkr: number; + currency: "PKR"; + customerId: string; + invoiceId?: string; + successUrl: string; + failureUrl: string; + metadata?: Record; +} + +export interface CreatePaymentResult { + paymentId: string; // internal payment.id + redirectUrl?: string; // for hosted page / app handoff + deepLinkUrl?: string; // for wallet app + qrCodeDataUrl?: string; // optional QR data +} + +export interface PaymentsService { + createPayment(params: CreatePaymentParams): Promise; + handleWebhook(payload: unknown, headers: Record): Promise; +} +``` + +When implementing `PaymentsService`: + +- Keep **provider-specific mapping** (signatures, fields, endpoints) inside + per-provider modules. +- Ensure every new provider **returns the same internal shape** so the rest of + the app does not care which gateway is used. + +### 4. Implement Checkout + Redirect Flows + +For each payment initiation: + +1. Create a **`payments` row** with status `pending`. +2. Call provider API (or generate a signed URL) via `PaymentsService`. +3. Return `redirectUrl` / `deepLinkUrl` to the client. +4. Do **not** mark `succeeded` until the webhook confirms it. + +UI responsibilities: + +- Show “Waiting for payment confirmation…” state. +- Poll a lightweight `/api/payments/:id` endpoint or rely on websockets/SSE to + update status. +- Surface **clear failure messaging** and retry options. + +### 5. Implement Webhook Handling (Next.js Example) + +Use a dedicated route for each provider or a unified handler that inspects a +header to detect the source. + +```ts +// app/api/payments/jazzcash/webhook/route.ts +import type { NextRequest } from "next/server"; +import { paymentsService } from "@/server/paymentsService"; + +export async function POST(req: NextRequest) { + const rawBody = await req.text(); + const headers: Record = {}; + req.headers.forEach((value, key) => { + headers[key.toLowerCase()] = value; + }); + + try { + await paymentsService.handleWebhook(rawBody, headers); + return new Response("ok", { status: 200 }); + } catch (error) { + // Log with correlation id; do not leak internals to provider + console.error("jazzcash webhook error", error); + return new Response("error", { status: 400 }); + } +} +``` + +Within `handleWebhook` you must: + +- **Verify signatures** using provider-specific secrets. +- Extract a stable `provider_payment_id` and map it to your internal + `payments` row. +- Use an **idempotency guard** to avoid double-processing: + +```ts +// Pseudocode inside repository layer +await db.transaction(async (tx) => { + const payment = await tx.payment.findByProviderId(providerPaymentId); + if (!payment || payment.status === "succeeded") { + return; // idempotent no-op + } + + await tx.payment.updateStatus(payment.id, "succeeded"); + await tx.invoice.markPaidIfFullySettled(payment.invoiceId); +}); +``` + +Never perform non-idempotent side effects (email, provisioning) **outside** +this transaction; instead, emit domain events or enqueue jobs driven by the +payment status change. + +### 6. Reconciliation and Reporting + +For PK gateways, **manual or semi-automated reconciliation** is common: + +- Schedule a **daily job** to fetch provider transactions for the last N days. +- Match on `provider_payment_id`, amount, and date window. +- Flag discrepancies: + - Provider reports success but local DB shows `pending`. + - Local DB shows `succeeded` but provider has no record (or refunded). + +Produce a simple reconciliation report: + +- Total successful payments (count, PKR sum) by provider. +- Unmatched payments needing human review. +- Breakdown per tenant for finance teams. + +### 7. Compliance and Risk (High-Level) + +You are **not** giving legal advice. Instead, you: + +- Remind the user about **State Bank of Pakistan (SBP)** regulations, + KYC/AML expectations, and transaction limits for wallets and bank transfers. +- Encourage: + - Proper **record-keeping** (timestamped payment events). + - Clear **refund policies** and support playbooks. + - Coordination with **accounting and legal** before going live. + +Always state explicitly: _“Validate this design with a qualified accountant or +lawyer familiar with Pakistani payments and SBP regulations before +production.”_ + +--- + +## Examples + +### Example 1: New B2B SaaS in Pakistan (Next.js) + +**User prompt** + +> We’re building a B2B SaaS for Pakistani SMEs on Next.js. +> Customers should pay in PKR via JazzCash or Easypaisa. +> Design the backend and give me sample code for the webhook. + +**How you respond** + +1. Clarify: + - Multi-tenant needs (one company vs many tenants). + - Flows: recurring subscriptions vs one-off invoices. +2. Propose the architecture described above with `PaymentsService`. +3. Provide: + - Minimal schema for `customers`, `subscriptions`, `invoices`, `payments`. + - A concrete `PaymentsService` interface and stub implementation. + - A Next.js webhook route similar to the example, with notes on where to + plug in JazzCash/Easypaisa-specific signature logic. + +You should end with a **checklist** (environment variables, staging vs prod +keys, test vs live mode). + +### Example 2: Existing Stripe SaaS Adding PK Wallets + +**User prompt** + +> We already run a SaaS with Stripe (USD) but want to support PKR via +> JazzCash/Easypaisa for Pakistani customers. How should we extend our stack? + +**How you respond** + +- Explain the **dual-rail strategy**: + - Keep Stripe for cards/international. + - Register JazzCash/Easypaisa as additional providers behind + `PaymentsService`. +- Add a field like `preferred_provider` on tenants/customers. +- Show a small TypeScript example: + +```ts +const provider: ProviderName = + customer.countryCode === "PK" ? "jazzcash" : "stripe-adapter"; + +await paymentsService.createPayment({ + provider, + amountPkr: customer.countryCode === "PK" ? 4500 : convertUsdToPkr(amountUsd), + currency: "PKR", + customerId: customer.id, + successUrl, + failureUrl, + metadata: { tenantId: tenant.id }, +}); +``` + +- Highlight migration steps: + - Keep existing Stripe invoices as-is. + - Use PK rails only for new Pakistani customers or new contracts. + - Update dashboards/reports to show totals by currency and provider. + +--- + +## Best Practices + +- **Treat everything as async** – do not mark payments `succeeded` on the + client redirect alone. +- Use **idempotency keys** and guarded updates in webhook handlers. +- Log a **correlation id** for each payment and include it in emails/support + tickets. +- Separate **test vs live** credentials and endpoints by environment. +- Normalize amounts to **integers of the smallest currency unit** (for + example paisa) in the database to avoid floating point issues. +- Keep **per-tenant and per-provider dashboards** so support can quickly see + what happened. + +--- + +## Edge Cases & Limitations + +Be explicit about tricky scenarios: + +- Customer closes the wallet app before completion → keep payment `pending` + and expose a **“resume payment”** link in the billing UI. +- Provider webhook is delayed or retried multiple times → rely on + idempotency logic, not on assumptions about exactly-once delivery. +- Partial refunds or chargebacks → store **negative adjustments** in a + separate table rather than mutating the original payment amount. + +Limitations of this skill: + +- Does not include real JazzCash/Easypaisa/bank API credentials or proprietary + documentation; you must consult official docs. +- Does not design POS or in-person payment flows. +- Does not replace a professional review for tax, accounting, or legal + compliance in Pakistan. + +--- + +## Related Skills + +Use this skill together with: + +- `@stripe-integration` – for global card payments and subscriptions. +- `@startup-metrics-framework` – to interpret PKR revenue and unit economics. +- `@analytics-tracking` – to track conversion, drop-off, and funnel health. +- `@pricing-strategy` – to decide PKR price points and packaging. +- `@senior-fullstack` or `@frontend-developer` – for high-quality UX and + implementation details around billing UIs. + diff --git a/skills_index.json b/skills_index.json index 19df6a0e..b4324cff 100644 --- a/skills_index.json +++ b/skills_index.json @@ -8779,6 +8779,16 @@ "source": "community", "date_added": "2026-02-27" }, + { + "id": "pakistan-payments-stack", + "path": "skills/pakistan-payments-stack", + "category": "development", + "name": "pakistan-payments-stack", + "description": "Design and implement Pakistani payment gateways (JazzCash, Easypaisa, local banks) in production SaaS stacks with robust PKR billing, webhooks, and reconciliation.", + "risk": "safe", + "source": "community", + "date_added": "2026-03-07" + }, { "id": "pandas", "path": "skills/pandas",