Payment Flow

Follow the arrows — money and goods, step by step

Seller
🛒
1. Creates payment link
Via WhatsApp bot (Kinyarwanda/English) or web dashboard — takes 30 seconds
Seller shares the link via WhatsApp, TikTok, Instagram — any channel
Buyer
💳
2. Pays via MTN MoMo / Airtel Money
No app, no account needed — clicks link, enters phone, approves on their phone
🛡 Merchant collection — not P2P. Fake screenshots impossible. MTN can't reverse it.
Pawapay (PSP)
🏦
3. Money held safely by Pawapay
Licensed Payment Service Provider — holds funds in their merchant account
🛡 TandPay NEVER touches the money. All funds stay with the licensed PSP.
TandPay
🔐
4. Two verification codes generated
Delivery Code
4827
Return Code
7193
Seller sees BOTH codes. Buyer sees NEITHER.
Delivery code travels with the goods. Return code is for returns. Both phone-locked to the buyer.
Seller
📦
5. Ships goods with delivery code
Code printed on receipt, written on package, or told to delivery person
Code is only revealed to buyer when they physically receive the package
Buyer
6. Buyer enters delivery code
Confirms "I received the goods" — like signing for a DHL package
🛡 Phone-locked — only the buyer's phone (same number that paid) can confirm. Not even the seller.
TandPay → Pawapay
💰
7. Payment released to seller's MoMo
TandPay instructs Pawapay → Pawapay sends money to seller's mobile money
Guaranteed payment — no chargebacks, no reversals, no "I'll pay you later"

If the seller never delivers → buyer does nothing → money auto-refunds after timeout.

Typical transaction completes in a few hours. Maximum timeout is configurable.

After Delivery — 4 Choices

The buyer inspects the goods, then decides

📦
Delivery Confirmed
Buyer entered the delivery code. Inspection window is now open.
Release Payment

"I'm satisfied"

Money → Seller now

No admin needed

↩️
Return Goods

Enter return code

Money → Buyer refund

No admin needed

⚠️
Open Dispute

"Something's wrong"

Money frozen → review

Only path needing admin

No Action

Auto-release

Money → Seller (48h)

Default — protects seller

3 out of 4 paths = zero admin intervention

Delivery vs Return

Same trust mechanism — reversed direction

📦 DELIVERY

Proves buyer RECEIVED

Buyer pays → codes generated
SELLER sees code · buyer doesn't
Code goes IN the package
Buyer gets package → finds code
Buyer enters code (phone-locked)
✅ Payment → Seller's MoMo

🛡 Code = proof of PHYSICAL RECEIPT

↩️ RETURN

Proves buyer RETURNED

Buyer & seller agree on return
SELLER has return code · buyer doesn't
Gives code to delivery person
Delivery person picks up package
Gives code to buyer AFTER pickup
↩️ Refund → Buyer's MoMo

🛡 Code = proof of PHYSICAL RETURN

Both codes generated when buyer pays. Seller sees both from day one.

Buyer NEVER sees either code until the physical handover.

Fraud Prevention

Every social commerce scam — and why it's impossible on TandPay

❌ SCAM
Fake MoMo Screenshot

Buyer sends doctored image of a payment

🛡 IMPOSSIBLE
Verified via Pawapay API

System checks real MoMo payment status — no screenshots

❌ SCAM
P2P Payment Reversal

Buyer calls MTN: "accidental transfer"

🛡 IMPOSSIBLE
Merchant collection, not P2P

Pawapay merchant account — MTN can't reverse it

❌ SCAM
Seller Disappears

Takes payment, blocks buyer, vanishes

🛡 PROTECTED
Auto-refund if no delivery

Money returns to buyer after timeout — zero effort

❌ SCAM
Unauthorized Confirmation

Seller or third party tries to confirm delivery

🛡 IMPOSSIBLE
Phone-locked to buyer

Only buyer's phone number can confirm — not even the seller

❌ SCAM
False Return Claim

Buyer claims return without actually returning goods

🛡 IMPOSSIBLE
Return code required

Code only given after delivery person picks up package — no return = no code = no refund

The Key Principle

Pawapay (licensed PSP) holds the money. TandPay provides the technology.
Every physical handover is verified by a code only the buyer can enter from their own phone.

How the Codes Are Secured

Two-factor verification: you need BOTH the physical code AND the authenticated phone session

TWO-FACTOR VERIFICATION MODEL
📦

Factor 1: The Code

Physical proof — comes from the package

4-digit random code generated using cryptographically secure random number generator

Stored as SHA-256 hash in the database — even if the database is breached, the plaintext code cannot be recovered

The seller sees the plaintext code to embed in the package. The buyer never sees it until physical handover

📱

Factor 2: Buyer's Phone

Identity proof — tied to MoMo number via OTP

When buyer pays, they verify their phone via SMS OTP — proves they own the MoMo number

System generates a buyer session token — stored as SHA-256 hash on the transaction, token saved in buyer's browser only

This token is unique to this buyer + this transaction — no other phone, no other browser can use it

BOTH REQUIRED TOGETHER

What Happens When Buyer Enters a Code

1

Buyer's browser sends: buyer_token + code (4 digits)

2

Server computes: SHA-256(buyer_token)

Compares with stored hash using constant-time comparison (prevents timing attacks)

3

Server computes: SHA-256(code)

Compares with stored delivery_code_hash or return_code_hash

4

Rate limit check: max 10 attempts per 15 minutes

Prevents brute-force guessing of the 4-digit code

Both checks pass → action triggered

Delivery code → release payment · Return code → process refund

Why No One Can Cheat

🏪

Seller

Knows the code but does NOT have the buyer_token. Without the token, entering the code is rejected.

Has code ✓ · Has token ✗ = BLOCKED

🕵️

Third Party

Might intercept the code but does NOT have the buyer_token (stored only in the buyer's browser).

Has code ✓ · Has token ✗ = BLOCKED

👤

Buyer (legit)

Has the token (from OTP verification) AND gets the code from the physical package.

Has code ✓ · Has token ✓ = ALLOWED

Cryptographic Techniques Used

#

SHA-256 Hashing

All codes and tokens are stored as one-way hashes. Even a database breach reveals nothing.

Constant-Time Comparison

Prevents timing attacks — response time is identical whether the code is right or wrong.

🔒

Rate Limiting

10 attempts per 15 minutes per transaction. Brute-forcing a 4-digit code requires 10,000 tries — blocked after 10.

📱

SMS OTP Phone Binding

Buyer's session token is created only after SMS OTP verification — proving ownership of the MoMo phone number.

This two-factor model follows the same principle as chip-and-PIN bank cards: something you HAVE (the code from the physical package) + something you ARE (the verified phone owner).