GoPay is a centralized payment gateway that standardizes multiple payment providers behind a single API. It eliminates the complexity of integrating with different payment systems by providing a unified interface for all payment operations.
Problem: Every payment provider has different APIs, authentication methods, callback mechanisms, and response formats.
Solution: GoPay standardizes everything into one consistent interface with multi-tenant support.
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ │ │ │ │ │
│ Your Apps │◄──►│ GoPay │◄──►│ Payment │
│ (Multi-Tenant) │ │ (Gateway) │ │ Providers │
│ │ │ │ │ │
└─────────────────┘ └─────────────────┘ └─────────────────┘
- Authentication: JWT tokens with auto-rotating secret keys
- Multi-Tenant: Each tenant has isolated provider configurations
- Database: PostgreSQL for configurations, logging, and analytics
- Rate Limiting: Tenant-specific rate limits with burst allowance
- Security: Auto-rotating JWT secrets, input validation, audit logging
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ │ │ │ │ │
│ Your App │───►│ GoPay │───►│ Provider │
│ │ │ │ │ │
│ │◄───│ │◄───│ │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
│ │ │
▼ ▼ ▼
1. Send request 2. Forward to 3. Process &
with JWT provider respond
Direct API flow for payments, refunds, and cancellations.
Phase 1: Payment Initialization
1. [App] ──POST /payments/provider──► [GoPay]
│ Request: { amount, cardInfo, callbackUrl: "app.com/callback" }
│
└─► [GoPay] ──► [Provider]
│ Modified: { callbackUrl: "gopay.com/v1/callback/provider?originalCallbackUrl=app.com/callback" }
│
└─► Response: { redirectUrl: "provider-3d-secure-link" }
Phase 2: User Redirect
2. [GoPay] ──Response──► [App]
│ Returns: { redirectUrl: "provider-3d-secure-link" }
│
└─► [App] redirects user to payment page
│
└─► User goes to [Provider 3D Secure Page]
Phase 3: 3D Secure Process
3. [User] completes 3D authentication on provider page
├─► Enter SMS code
├─► Bank authentication
└─► Payment confirmation
Phase 4: Callback Handling
4. [Provider] ──Callback──► [GoPay]
│ URL: gopay.com/v1/callback/provider?originalCallbackUrl=app.com/callback
│ Data: { paymentId, status, transactionId }
│
└─► [GoPay] processes result
│
└─► [GoPay] ──Redirect──► [App]
│ URL: app.com/callback?success=true&paymentId=123&status=successful
│
└─► [App] shows success/failure page to user
Complete 3D Secure Flow:
[Your App] → [GoPay] → [Provider] → [3D Page] → [Provider] → [GoPay] → [Your App]
│ │ │ │ │ │ │
│ │ │ │ │ │ │
▼ ▼ ▼ ▼ ▼ ▼ ▼
1. Payment 2. Forward 3. Return 4. User 5. Callback 6. Process 7. Final
request with 3D link auth to GoPay & redirect result
callback
- Authenticate → Get JWT token (
POST /v1/auth/login
) - Configure → Set provider credentials (
POST /v1/config/tenant
) - Process → Create payments using standardized API
- Handle → Automatic callback/webhook management
- Monitor → Track transactions via dashboard & logs
Provider | Status | Region | Features |
---|---|---|---|
Paycell | Production | Turkey | Payment, 3D, Refund, Cancel |
Nkolay | Production | Turkey | Payment, 3D, Refund, Cancel |
İyzico | Development | Turkey | Payment, 3D, Refund, Cancel |
OzanPay | Development | Turkey | Payment, 3D, Refund, Cancel |
Papara | Development | Turkey | Payment, 3D, Refund, Cancel |
PayTR | Development | Turkey | Payment, 3D, Refund, Cancel |
PayU | Development | Global | Payment, 3D, Refund, Cancel |
Stripe | Development | Global | Payment, 3D, Refund, Cancel |
git clone https://github.com/mstgnz/gopay.git
cd gopay
# Configure environment
cp .env.example .env
# Edit .env with your database settings
# Run with Docker
docker-compose up -d
# Or run directly
go run ./cmd/main.go
# First user registration (becomes admin)
curl -X POST http://localhost:9999/v1/auth/register \
-H "Content-Type: application/json" \
-d '{
"username": "admin",
"password": "securepassword123"
}'
# Login to get JWT token
curl -X POST http://localhost:9999/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"username": "admin",
"password": "securepassword123"
}'
# Configure payment provider (tenant-specific)
curl -X POST http://localhost:9999/v1/config/tenant \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"provider": "iyzico",
"environment": "test",
"configs": [
{"key": "apiKey", "value": "your-api-key"},
{"key": "secretKey", "value": "your-secret-key"}
]
}'
# Create direct payment (no 3D Secure)
curl -X POST http://localhost:9999/v1/payments/iyzico \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"amount": 100.50,
"currency": "TRY",
"customer": {
"name": "John",
"surname": "Doe",
"email": "[email protected]"
},
"cardInfo": {
"cardHolderName": "John Doe",
"cardNumber": "5528790000000008",
"expireMonth": "12",
"expireYear": "2030",
"cvv": "123"
},
"use3D": false
}'
# Response
{
"success": true,
"status": "successful",
"paymentId": "12345",
"transactionId": "67890",
"amount": 100.50,
"currency": "TRY"
}
# Step 1: Initialize 3D Secure payment
curl -X POST http://localhost:9999/v1/payments/iyzico \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"amount": 100.50,
"currency": "TRY",
"customer": {
"name": "John",
"surname": "Doe",
"email": "[email protected]"
},
"cardInfo": {
"cardHolderName": "John Doe",
"cardNumber": "5528790000000008",
"expireMonth": "12",
"expireYear": "2030",
"cvv": "123"
},
"use3D": true,
"callbackUrl": "https://yourapp.com/payment-callback"
}'
# Step 1 Response: You get redirect URL
{
"success": true,
"status": "pending",
"paymentId": "12345",
"redirectUrl": "https://provider-3dsecure.com/auth?token=xyz",
"message": "3D Secure authentication required"
}
3D Secure Flow Implementation:
<?php
// Step 2: Your app redirects user to 3D page
session_start();
$_SESSION['payment_id'] = $paymentId; // Store for later
header("Location: " . $redirectUrl); // User goes to bank page
?>
<?php
// Step 3: Handle callback (yourapp.com/payment-callback)
session_start();
if($_GET['success'] === 'true') {
$paymentId = $_GET['paymentId'];
$status = $_GET['status'];
$transactionId = $_GET['transactionId'];
// Payment successful - redirect to success page
header("Location: /payment-success?payment=" . $paymentId);
} else {
$error = $_GET['error'];
// Payment failed - redirect to error page
header("Location: /payment-failed?error=" . urlencode($error));
}
?>
Complete 3D Flow:
- Your App → Send payment request → GoPay
- GoPay → Get
redirectUrl
→ Your App - Your App → Redirect user → Provider 3D Page
- User → Complete 3D auth → Provider
- Provider → Callback → GoPay → Your App
- Your App → Show result page → User
- Auto-Rotating Secret Keys: JWT secret regenerates on service restart
- Token Expiry: 24-hour token lifetime with refresh capability
- Tenant Isolation: Each tenant has separate configurations and data
- Tenant-Based: Individual limits per tenant
- Action-Specific: Different limits for payment, refund, status checks
- Burst Allowance: Additional requests above base limits
- IP Protection: Rate limiting for unauthenticated requests
- Input Validation: Comprehensive request validation
- SQL Injection Protection: Parameterized queries
- Audit Logging: All operations logged with tenant isolation
- Sensitive Data Masking: Card numbers and keys masked in logs
- Tenant Isolation: Complete separation of configurations and data
- JWT-Based: Tenant information embedded in authentication tokens
- Scalable: Support for unlimited tenants with isolated rate limits
- Standard Payments: Direct card payments
- 3D Secure: Enhanced security with bank authentication
- Refunds: Full and partial refund support
- Status Tracking: Real-time payment status monitoring
- Cancellations: Payment cancellation support
- Real-Time Dashboard: Payment statistics and performance metrics
- Provider Analytics: Success rates and error tracking per provider
- Activity Logs: Complete audit trail with tenant isolation
- PostgreSQL Integration: Structured logging and analytics
POST /v1/auth/login # User login
POST /v1/auth/register # First user registration
POST /v1/auth/create-tenant # Create new tenant (admin only)
POST /v1/auth/refresh # Refresh JWT token
POST /v1/config/tenant # Configure payment provider
GET /v1/config/tenant # Get tenant configuration
DELETE /v1/config/tenant # Delete tenant configuration
POST /v1/payments/{provider} # Create payment
GET /v1/payments/{provider}/{paymentID} # Check payment status
DELETE /v1/payments/{provider}/{paymentID} # Cancel payment
POST /v1/payments/{provider}/refund # Process refund
# 3D Secure Callbacks (Automatic - Provider calls these)
GET|POST /v1/callback/{provider} # 3D Secure completion callback
Parameters: ?originalCallbackUrl=yourapp.com/callback&paymentId=123&status=success
# Payment Webhooks (Automatic - Provider notifications)
POST /v1/webhooks/{provider} # Payment status notifications
Callback Flow:
- Provider redirects user to:
gopay.com/v1/callback/iyzico?originalCallbackUrl=yourapp.com/callback
- GoPay processes and redirects to:
yourapp.com/callback?success=true&paymentId=123&status=successful
You don't call these endpoints directly - they're called by payment providers.
GET /v1/analytics/dashboard # Dashboard statistics
GET /v1/logs/{provider} # Payment logs
GET /health # Health check
- 🌐 API Documentation: Interactive API Docs
- 📖 Provider Guides: Individual provider documentation in
provider/*/README.md
- 🔧 Examples: Complete examples in
examples/
directory - 🎯 Postman Collections: Available in each provider directory
docker-compose up -d
kubectl apply -f k8s/
# Build binary
go build -o gopay ./cmd/main.go
# Run with PostgreSQL
./gopay
# Database
DB_HOST=localhost
DB_PORT=5432
DB_NAME=gopay
DB_USER=postgres
DB_PASSWORD=password
# Application
APP_PORT=9999
APP_URL=http://localhost:9999
SECRET_KEY=your-secret-key
# Rate Limiting
TENANT_GLOBAL_RATE_LIMIT=100
TENANT_PAYMENT_RATE_LIMIT=50
TENANT_REFUND_RATE_LIMIT=20
- Fork the repository
- Create a feature branch
- Add tests for your changes
- Submit a pull request
- Implement the
provider.PaymentProvider
interface - Add provider package under
provider/{provider}/
- Create comprehensive README and tests
- Register provider in
provider/{provider}/register.go
This project is licensed under the Boost Software License 1.0.
- 📖 Documentation: API Docs
- 🐛 Issues: GitHub Issues
- 💡 Discussions: GitHub Discussions
🚀 Ready to integrate payments? Start with the API documentation or check out the examples!