👛 Wallet Payments (EGP)
Accept Egyptian Pound payments from Gammal Tech Wallet. Instant settlement, zero chargebacks, one-click for returning users.
Why Wallet Payments?
Instant Settlement
Funds available immediately
Zero Chargebacks
Pre-funded wallet = no disputes
One-Click Payment
No card entry for users
Low Fees
Best rates for EGP
Wallet payments are ideal for Egyptian users who may not have international cards or prefer local payment methods. Users fund their wallet via mobile wallets, retail payment points, or bank transfer.
Method Reference
Initiates a wallet payment. Opens a confirmation popup if needed, deducts from user's wallet, and calls your delivery callback on success.
| Parameter | Type | Description |
|---|---|---|
amount |
number |
Amount in EGP (minimum 1, integers recommended) |
description |
string |
What the user is paying for (shown in receipt) |
onDeliver |
function(payment) |
Callback when payment succeeds. Receives payment object. |
Basic Usage
// Charge 50 EGP for a product
GammalTech.pay(50, 'Digital Sticker Pack', function(payment) {
// Payment successful!
console.log('Payment ID:', payment.id);
console.log('Amount:', payment.amount, 'EGP');
// Deliver the product to the user
unlockStickerPack(payment.user_id);
// Confirm delivery
GammalTech.payment.confirmDelivery(payment.id);
});
Payment Flow
User Clicks Pay
Your app calls GammalTech.pay() with amount and description.
Balance Check
SDK checks if user has sufficient wallet balance.
Confirmation (if needed)
User confirms payment in popup (first time or large amounts).
Deduction
Amount deducted from user's wallet instantly.
Callback
Your onDeliver function is called with payment details.
Deliver & Confirm
You deliver the product and call confirmDelivery().
Payment Object
The onDeliver callback receives a payment object with these properties:
Always store payment.id in your database. You'll need it for refunds, support queries, and reconciliation.
Complete Example
Here's a full checkout implementation:
<!DOCTYPE html>
<html>
<head>
<title>Checkout</title>
<script src="https://api.gammal.tech/sdk-web.js"></script>
</head>
<body>
<div id="product">
<h1>Premium Course Access</h1>
<p>Get lifetime access to all lessons</p>
<p class="price">299 EGP</p>
<button id="buyBtn">Buy Now</button>
</div>
<div id="success" style="display:none">
<h1>🎉 Thank You!</h1>
<p>Your purchase is complete.</p>
<a href="/courses">Start Learning →</a>
</div>
<script>
const PRODUCT = {
name: 'Premium Course Access',
price: 299,
id: 'course_premium'
};
document.getElementById('buyBtn').addEventListener('click', async () => {
// Check if logged in first
if (!GammalTech.isLoggedIn()) {
await GammalTech.login();
if (!GammalTech.isLoggedIn()) return;
}
// Initiate payment
GammalTech.pay(PRODUCT.price, PRODUCT.name, async (payment) => {
// Payment successful!
console.log('Payment completed:', payment.id);
// Save to your backend
await fetch('/api/purchases', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
payment_id: payment.id,
product_id: PRODUCT.id,
user_id: payment.user_id,
amount: payment.amount
})
});
// Confirm delivery to Gammal Tech
await GammalTech.payment.confirmDelivery(payment.id);
// Show success UI
document.getElementById('product').style.display = 'none';
document.getElementById('success').style.display = 'block';
});
});
</script>
</body>
</html>
Handling Errors
The payment may fail for various reasons. Handle them gracefully:
try {
GammalTech.pay(100, 'Product', (payment) => {
// Success
deliverProduct(payment);
});
} catch (error) {
switch (error.code) {
case 'INSUFFICIENT_BALANCE':
alert('Not enough balance. Please top up your wallet.');
// Optionally redirect to wallet top-up
break;
case 'USER_CANCELLED':
console.log('User cancelled the payment');
break;
case 'NOT_LOGGED_IN':
alert('Please log in to make a purchase');
GammalTech.login();
break;
default:
alert('Payment failed. Please try again.');
console.error(error);
}
}
If the user doesn't have enough balance, guide them to top up their wallet at my.gammal.tech/wallet. You can deep-link: https://my.gammal.tech/wallet?amount=100
Best Practices
Always Confirm Delivery
Call confirmDelivery() after you've successfully delivered the product. This completes the transaction and updates the user's purchase history.
Store Payment IDs
Save every payment.id in your database linked to the user and product. This is essential for customer support and refunds.
Use Clear Descriptions
The description appears on the user's receipt and wallet history. Make it clear: "Premium Plan - March 2025" is better than "Subscription".
Handle Interrupted Payments
If a payment succeeds but your callback fails (e.g., network error), use settlePending() on page load. See Payment Recovery.
AI Prompt for Vibe Coding
Wallet PaymentsCopy this prompt for help with wallet payment implementation: