Configuration Payram
Configurez votre backend pour se connecter à un serveur Payram auto-hébergé et validez la connexion avec des tests de connectivité.
name: setup-payram description: Configure and validate connectivity to a self-hosted Payram server
Setup Payram
Configure your backend to connect to a self-hosted Payram server and validate the connection.
Overview
This skill guides you through:
- Creating the required
.envconfiguration - Understanding Payram's authentication model
- Testing connectivity to your Payram instance
- Troubleshooting common connection issues
When to Use
- Starting a new Payram integration
- Validating existing Payram configuration
- Troubleshooting connection errors
- Setting up a new environment (staging, production)
Prerequisites
You must have:
- A self-hosted Payram server deployed and accessible
- Admin access to the Payram dashboard
- An API key generated from the dashboard (Settings → Accounts → API Keys)
Instructions
Step 1: Create Environment Configuration
Create a .env file in your project root with the following variables:
# Payram REST base URL (include protocol, no trailing slash)
PAYRAM_BASE_URL=https://your-payram-server.example
# Payram API key (from dashboard Settings → Accounts → API Keys)
PAYRAM_API_KEY=pk_live_your_actual_key_here
Required Variables:
PAYRAM_BASE_URL: Full URL to your self-hosted Payram instancePAYRAM_API_KEY: Project-scoped API key from the Payram dashboard
Important: Never commit .env files to version control. Add .env to your .gitignore.
Step 2: Understand Authentication
Payram uses header-based authentication:
API-Key: your_api_key_here
NOT Authorization: Bearer ... - this will fail with 401.
The API key must be:
- Sent in the
API-Keyheader (case-sensitive) - Generated for the specific project/workspace you're integrating
- Kept secret and never exposed in client-side code
Step 3: Test Connectivity
Create a test script to validate your connection. The connection test creates a minimal payment request to verify:
- Network reachability
- API key validity
- Correct authentication setup
Node.js/TypeScript (Using Payram SDK)
Install SDK:
npm install payram dotenv
Test Script:
import { Payram, isPayramSDKError } from 'payram';
import dotenv from 'dotenv';
dotenv.config();
const baseUrl = process.env.PAYRAM_BASE_URL;
const apiKey = process.env.PAYRAM_API_KEY;
if (!baseUrl || !apiKey) {
console.error('❌ Missing PAYRAM_BASE_URL or PAYRAM_API_KEY in .env');
process.exit(1);
}
async function testConnection() {
try {
// Initialize Payram SDK
const payram = new Payram({
apiKey,
baseUrl,
config: {
timeoutMs: 10_000,
maxRetries: 2,
},
});
console.log('🔄 Testing connection to Payram...');
console.log(` Base URL: ${baseUrl}`);
// Create a minimal test payment
const checkout = await payram.payments.initiatePayment({
customerEmail: 'test@example.com',
customerId: 'connectivity-test',
amountInUSD: 1,
});
console.log('✅ Connection successful!');
console.log(` Reference ID: ${checkout.reference_id}`);
console.log(` Checkout URL: ${checkout.url}`);
return true;
} catch (error) {
console.error('❌ Connection failed');
if (isPayramSDKError(error)) {
console.error(` Status: ${error.status}`);
console.error(` Error: ${error.error}`);
console.error(` Request ID: ${error.requestId}`);
console.error(` Retryable: ${error.isRetryable}`);
} else {
console.error(` Error: ${error instanceof Error ? error.message : String(error)}`);
}
return false;
}
}
testConnection();
Python (Using requests)
Install dependencies:
pip install requests python-dotenv
Test Script:
import os
import requests
from dotenv import load_dotenv
load_dotenv()
base_url = os.getenv('PAYRAM_BASE_URL')
api_key = os.getenv('PAYRAM_API_KEY')
if not base_url or not api_key:
print('❌ Missing PAYRAM_BASE_URL or PAYRAM_API_KEY in .env')
exit(1)
def test_connection():
try:
print('🔄 Testing connection to Payram...')
print(f' Base URL: {base_url}')
endpoint = f"{base_url}/api/v1/payment"
headers = {
'API-Key': api_key,
'Content-Type': 'application/json',
'Accept': 'application/json',
}
payload = {
'customerEmail': 'test@example.com',
'customerId': 'connectivity-test',
'amountInUSD': 1,
}
response = requests.post(endpoint, json=payload, headers=headers, timeout=10)
if response.status_code in [200, 201]:
data = response.json()
print('✅ Connection successful!')
print(f" Reference ID: {data.get('reference_id', 'N/A')}")
print(f" Checkout URL: {data.get('url', 'N/A')}")
return True
else:
print('❌ Connection failed')
print(f" Status: {response.status_code}")
print(f" Response: {response.text}")
return False
except requests.exceptions.RequestException as e:
print('❌ Connection failed')
print(f" Error: {str(e)}")
return False
if __name__ == '__main__':
test_connection()
Go (Using net/http)
Test Script:
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
"github.com/joho/godotenv"
)
type PaymentRequest struct {
CustomerEmail string `json:"customerEmail"`
CustomerID string `json:"customerId"`
AmountInUSD float64 `json:"amountInUSD"`
}
type PaymentResponse struct {
ReferenceID string `json:"reference_id"`
URL string `json:"url"`
}
func testConnection() bool {
godotenv.Load()
baseURL := os.Getenv("PAYRAM_BASE_URL")
apiKey := os.Getenv("PAYRAM_API_KEY")
if baseURL == "" || apiKey == "" {
fmt.Println("❌ Missing PAYRAM_BASE_URL or PAYRAM_API_KEY in .env")
return false
}
fmt.Println("🔄 Testing connection to Payram...")
fmt.Printf(" Base URL: %s\n", baseURL)
payload := PaymentRequest{
CustomerEmail: "test@example.com",
CustomerID: "connectivity-test",
AmountInUSD: 1.0,
}
body, _ := json.Marshal(payload)
client := &http.Client{Timeout: 10 * time.Second}
req, err := http.NewRequest("POST", baseURL+"/api/v1/payment", bytes.NewBuffer(body))
if err != nil {
fmt.Printf("❌ Failed to create request: %v\n", err)
return false
}
req.Header.Set("API-Key", apiKey)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept", "application/json")
resp, err := client.Do(req)
if err != nil {
fmt.Printf("❌ Connection failed: %v\n", err)
return false
}
defer resp.Body.Close()
if resp.StatusCode == 200 || resp.StatusCode == 201 {
var result PaymentResponse
bodyBytes, _ := io.ReadAll(resp.Body)
json.Unmarshal(bodyBytes, &result)
fmt.Println("✅ Connection successful!")
fmt.Printf(" Reference ID: %s\n", result.ReferenceID)
fmt.Printf(" Checkout URL: %s\n", result.URL)
return true
} else {
fmt.Printf("❌ Connection failed: Status %d\n", resp.StatusCode)
bodyBytes, _ := io.ReadAll(resp.Body)
fmt.Printf(" Response: %s\n", string(bodyBytes))
return false
}
}
func main() {
testConnection()
}
PHP (Using cURL)
Test Script:
<?php
require __DIR__ . '/vendor/autoload.php';
use Dotenv\Dotenv;
$dotenv = Dotenv::createImmutable(__DIR__);
$dotenv->load();
$baseUrl = $_ENV['PAYRAM_BASE_URL'] ?? null;
$apiKey = $_ENV['PAYRAM_API_KEY'] ?? null;
if (!$baseUrl || !$apiKey) {
echo "❌ Missing PAYRAM_BASE_URL or PAYRAM_API_KEY in .env\n";
exit(1);
}
function testConnection($baseUrl, $apiKey) {
echo "🔄 Testing connection to Payram...\n";
echo " Base URL: $baseUrl\n";
$payload = [
'customerEmail' => 'test@example.com',
'customerId' => 'connectivity-test',
'amountInUSD' => 1,
];
$ch = curl_init($baseUrl . '/api/v1/payment');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'API-Key: ' . $apiKey,
'Content-Type: application/json',
'Accept: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
]);
$response = curl_exec($ch);
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
if ($error) {
echo "❌ Connection failed: $error\n";
return false;
}
if ($statusCode === 200 || $statusCode === 201) {
$data = json_decode($response, true);
echo "✅ Connection successful!\n";
echo " Reference ID: " . ($data['reference_id'] ?? 'N/A') . "\n";
echo " Checkout URL: " . ($data['url'] ?? 'N/A') . "\n";
return true;
} else {
echo "❌ Connection failed: Status $statusCode\n";
echo " Response: $response\n";
return false;
}
}
testConnection($baseUrl, $apiKey);
Java (Using HttpClient)
Test Script:
package com.example.payram;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import io.github.cdimascio.dotenv.Dotenv;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
public class ConnectionTest {
public static void main(String[] args) {
Dotenv dotenv = Dotenv.load();
String baseUrl = dotenv.get("PAYRAM_BASE_URL");
String apiKey = dotenv.get("PAYRAM_API_KEY");
if (baseUrl == null || apiKey == null) {
System.out.println("❌ Missing PAYRAM_BASE_URL or PAYRAM_API_KEY in .env");
System.exit(1);
}
testConnection(baseUrl, apiKey);
}
public static boolean testConnection(String baseUrl, String apiKey) {
try {
System.out.println("🔄 Testing connection to Payram...");
System.out.println(" Base URL: " + baseUrl);
// Create JSON payload
ObjectMapper mapper = new ObjectMapper();
ObjectNode payload = mapper.createObjectNode();
payload.put("customerEmail", "test@example.com");
payload.put("customerId", "connectivity-test");
payload.put("amountInUSD", 1);
// Build HTTP request
HttpClient client = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10))
.build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(baseUrl + "/api/v1/payment"))
.header("API-Key", apiKey)
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(mapper.writeValueAsString(payload)))
.timeout(Duration.ofSeconds(10))
.build();
// Send request
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200 || response.statusCode() == 201) {
ObjectNode result = (ObjectNode) mapper.readTree(response.body());
System.out.println("✅ Connection successful!");
System.out.println(" Reference ID: " + result.get("reference_id").asText());
System.out.println(" Checkout URL: " + result.get("url").asText());
return true;
} else {
System.out.println("❌ Connection failed: Status " + response.statusCode());
System.out.println(" Response: " + response.body());
return false;
}
} catch (Exception e) {
System.out.println("❌ Connection failed: " + e.getMessage());
return false;
}
}
}
Step 4: Interpret Results
Success (200/201):
{
"checkout": {
"id": "...",
"url": "https://...",
...
}
}
Your configuration is correct and Payram is reachable.
401 Unauthorized:
- Check that
API-Keyheader is used (notAuthorization) - Verify the API key is correct and hasn't been revoked
- Ensure the key is for the correct project/workspace
404 Not Found:
- Verify
PAYRAM_BASE_URLis correct - Check for typos in the endpoint path
- Confirm Payram is deployed and running
Network Errors:
- Verify firewall rules allow outbound HTTPS
- Check DNS resolution of your Payram domain
- Confirm SSL certificates are valid
Best Practices
-
Environment Separation
- Use different API keys for staging vs production
- Never share API keys between environments
- Rotate keys regularly
-
Security
- Store API keys in secure secret management systems (AWS Secrets Manager, Vault, etc.)
- Never log full API keys
- Use environment-specific
.envfiles (.env.staging,.env.production)
-
Error Handling
- Always check response status codes
- Log failures with context but without sensitive data
- Implement retry logic with exponential backoff for network errors
-
Validation
- Test connectivity before deploying to production
- Run connectivity tests as part of CI/CD health checks
- Monitor connection health in production with periodic pings
Troubleshooting
"Missing PAYRAM_BASE_URL or PAYRAM_API_KEY"
Cause: Environment variables not loaded.
Solution:
- Ensure
.envfile exists in project root - Verify
.envcontains both variables - Check that your code loads
.env(e.g.,dotenv.config()in Node,load_dotenv()in Python)
"401 Unauthorized" or "Authentication Failed"
Cause: Invalid or missing API key.
Solution:
- Confirm you're using
API-Keyheader, notAuthorization - Regenerate API key in Payram dashboard if needed
- Check for extra whitespace in
.envvalues
"Network error" or "Connection refused"
Cause: Payram server unreachable.
Solution:
- Verify
PAYRAM_BASE_URLincludes protocol (https://) - Check firewall rules and network connectivity
- Confirm Payram service is running (
systemctl status payram)
"404 Not Found"
Cause: Wrong endpoint or base URL.
Solution:
- Remove trailing slashes from
PAYRAM_BASE_URL - Verify endpoint path is
/api/v1/payment - Check Payram version compatibility
Related Skills
integrate-payments- After setup, implement payment flowsintegrate-payouts- Configure outbound payment capabilitieshandle-webhooks- Receive Payram event notifications
Skills similaires
Expert Next.js App Router
Un skill qui transforme Claude en expert Next.js App Router.
Générateur de README
Crée des README.md professionnels et complets pour vos projets.
Rédacteur de Documentation API
Génère de la documentation API complète au format OpenAPI/Swagger.