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

Perfect for Egyptian Market

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

GammalTech.pay(amount, description, onDeliver)

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

Simple payment
// 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

1

User Clicks Pay

Your app calls GammalTech.pay() with amount and description.

2

Balance Check

SDK checks if user has sufficient wallet balance.

3

Confirmation (if needed)

User confirms payment in popup (first time or large amounts).

4

Deduction

Amount deducted from user's wallet instantly.

5

Callback

Your onDeliver function is called with payment details.

6

Deliver & Confirm

You deliver the product and call confirmDelivery().

Payment Object

The onDeliver callback receives a payment object with these properties:

{ "id": "pay_abc123xyz", // Unique payment ID "amount": 50, // Amount in EGP "currency": "EGP", // Always EGP for wallet "description": "Digital Sticker Pack", "user_id": "usr_def456", // Gammal Tech user ID "status": "completed", // Payment status "created_at": "2025-01-05T14:30:00Z" }
💡 Store the Payment ID

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:

checkout.html
<!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:

Error handling
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);
    }
}
⚠️ Insufficient Balance

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 Payments

Copy this prompt for help with wallet payment implementation:

I'm implementing Gammal Tech Wallet payments (EGP). Method: GammalTech.pay(amount, description, onDeliver) Parameters: - amount: number (EGP, minimum 1) - description: string (shown on receipt) - onDeliver: function(payment) - called on success Payment object received in callback: { id: "pay_xxx", // Store this! amount: 50, // EGP amount currency: "EGP", description: "...", user_id: "usr_xxx", status: "completed" } Flow: 1. Check GammalTech.isLoggedIn() first 2. Call GammalTech.pay() 3. In onDeliver: save to your DB, deliver product 4. Call GammalTech.payment.confirmDelivery(payment.id) Error codes: INSUFFICIENT_BALANCE, USER_CANCELLED, NOT_LOGGED_IN Please help me: [DESCRIBE YOUR WALLET PAYMENT TASK]