ShapLink Case Study
This case study begins before development. It sets the goal, the scope, and the proof to collect. After delivery we will replace the plan sections with real results and evidence.
One line outcome
Create one payment link for any rail in South Africa with one API and one dashboard. Give merchants faster cash and clean records without extra work.
Context
Small teams and solo merchants need to accept payments across many rails. Each rail has a different process and a different report. People waste time moving between portals and fixing mismatched data.
Problem statement
Accepting and tracking payments across many rails is slow and messy. It hurts cash flow, support, and trust.
Users
- Merchant owner or admin
- Finance person or bookkeeper
- Developer who integrates the API
Goal and measure
Goal. Reduce time to create a payment link and to reconcile a payment.
Measure. Time to create a link and receive a status update. Aim under two minutes. Webhook delivery success. Aim above ninety nine percent. Reconciliation time per payout. Aim under five minutes per day.
Success criteria and acceptance tests
[ ] A link can be created by API and by dashboard in under two minutes
[ ] Customer can pay through two or more rails on day one
[ ] Webhook delivery success above ninety nine percent with retry and backoff
[ ] Dashboard shows payment status within five seconds of event receipt
[ ] Daily export matches the source rails within one percent by count and amount
[ ] No personal data is logged in plain text
[ ] Access control by role with audit trail of changes
Scope and out of scope
In scope. Link creation, payment status, refunds, daily exports, simple reports, and support for two to four rails to start.
Out of scope. Point of sale hardware, full dispute management, and custom risk scoring.
Approach in simple words
Start with a clean API and a simple dashboard. Use a queue for events. Use a background worker for retries and exports. Keep a clean data model and clear logs. Choose two rails for the first release and add more after the system is stable.
AI role
Use AI to draft client libraries and tests. Use AI to summarise logs and incident timelines. Do not use AI for core payment logic. All AI use has human review and tests.
Architecture plan
Gateway means the front door of the system. It ends TLS, blocks bad traffic, applies rate limits, and forwards safe requests to the API service. It does not run business rules and it does not read or write data.
High level flow
- Client calls Gateway and the API service writes and reads the Database.
- The API service pushes work to a Queue and Workers update the Database.
- Payment rails send events to the Webhook receiver which enqueues work for Workers.
- The Dashboard reads live status from the API service and exports files.
- Observability collects logs, metrics, and traces. The Status page shows public health.
AWS serverless mapping
- Gateway. Amazon API Gateway with AWS WAF in front.
- API service. AWS Lambda in Node or dot NET, or AWS App Runner if we prefer containers.
- Database. Amazon Aurora serverless for Postgres to start. DynamoDB is an option if we want key value.
- Queue. Amazon SQS standard for tasks and retries.
- Workers. AWS Lambda functions triggered by SQS.
- Webhook receiver. API Gateway route to a Lambda with request signatures.
- Exports and schedules. Amazon EventBridge rules that trigger Lambdas.
- Files. Amazon S3 for CSV exports with signed links.
- Observability. Amazon CloudWatch logs and metrics with X Ray traces.
- Secrets. AWS Secrets Manager and AWS KMS.
- Identity. Amazon Cognito for sign in and role access.
- Status page. A small static site on S3 and CloudFront that reads a health feed.
Business requirements
- Create a payment link with amount, currency, context text, and expiry
- Send a short link to the customer by email or message
- Support refunds by amount and by full payment
- Show status in the dashboard and by API
- Export a daily CSV and a monthly CSV for accounts
- Support roles. Owner, finance, and developer
- Metered pricing with a free tier and a clear upgrade path
User stories
- As a merchant owner I create a link and send it to a customer in under two minutes
- As a finance person I download a daily CSV that matches the source rails
- As a developer I create a link by API and receive a webhook when status changes
- As a developer I retry a webhook and get a clear response code
API outline
POST /v1/links
GET /v1/links/{id}
POST /v1/links/{id}/refunds
GET /v1/events?after=cursor
Data contracts
{
"LinkCreate": {
"amount": "number",
"currency": "string",
"reference": "string",
"expiresAt": "ISO datetime"
},
"Link": {
"id": "string",
"url": "string",
"status": "pending or paid or expired or refunded"
},
"Event": {
"id": "string",
"type": "payment.paid or payment.refunded or link.expired",
"createdAt": "ISO datetime",
"data": {}
}
}
Security and privacy
- Validate all input on the server and encode all output
- Role based access control with least privilege
- Token scopes for API keys
- TLS in transit and encryption at rest
- Secrets in a secret manager and never in logs
- Personal data redacted in logs and in events
- Clear data retention and deletion policy
Reliability and observability
- Idempotency key on all writes
- Retries with backoff for external calls
- Circuit breaker for rail outages
- Logs, metrics, and traces with a request id
- Service level objectives for uptime and latency
- Status page with incident notes
Trust signals for buyers
- Public roadmap and change log with dates
- Public status page with history
- Security and privacy pages with clear diagrams
- Evaluation notes for webhook delivery and mismatch rates
- Fair refund policy
Evidence to collect after launch
- Time to create a link by API and by dashboard
- Webhook delivery success rate by day
- P50 and P95 latency from event to visible status
- CSV match rate by count and amount
- Support tickets per one hundred payments
- Merchant quotes and short stories
Risks and mitigations
- Rail outage. Use retries and circuit breaker. Show clear messages and fallbacks
- Fraud risk. Use rate limits and simple rules. Add review for large amounts
- Data mismatch. Build a daily compare job and notify on difference
- Cost drift. Set budgets and alerts. Use back pressure and timeouts
Implementation plan
Each step ends with a short demo and a small note of proof.
Step 1. Foundation
- Decision brief and goals
- Identity and access. Owner, finance, and developer roles
- Empty dashboard and a live health page
- Logs and metrics wired to observability
Proof
- Health page reports current status
- Role check works with a small test page
Step 2. Links and status
- Create link by API and in the dashboard
- Short link returned to the merchant
- Status page for a single link
Proof
- Time to create a link under two minutes by both paths
- Logs show redacted fields only
Step 3. Webhook in and out
- Receive events from the first rail
- Update status and enqueue merchant webhooks
- Retry on failure with backoff
Proof
- Webhook delivery success above ninety nine percent in a controlled test
- Dashboard shows new status within five seconds of event receipt
Step 4. Exports and refunds
- Daily CSV and monthly CSV
- Refund by amount and by full value
Proof
- Daily export matches the source rail within one percent by count and amount
- Refund events appear in the log and in the dashboard
Step 5. Hardening and public signals
- Load and failure drills
- Status page with history and incident notes
- Privacy and security pages with simple diagrams
Proof
- P50 and P95 latency goals are met for read and write
- Incident notes are clear and dated
Review checklist
[ ] One line outcome is clear
[ ] Goal and measure are named with targets
[ ] Scope is set and limits are clear
[ ] AWS mapping is written
[ ] API and data contracts are written
[ ] Security and privacy are covered
[ ] Reliability and observability are covered
[ ] Trust signals are planned
[ ] Evidence to collect is listed
[ ] Risks have owners and actions
[ ] Timeline is realistic
Closing note
Write the case study plan before you write the code. It guides the work and tells you what proof to collect. After delivery, replace the plan with the real story and the numbers.