{
  "info": {
    "_postman_id": "f7f2fbb6-9e5c-46bb-8d5d-solimi-api-v1",
    "name": "SOLIMI Payment Collection API - Partner Quickstart",
    "description": "Collection Postman pour tester rapidement l'API publique de collecte de paiement SOLIMI. Le script de pre-request calcule automatiquement les headers HMAC: x-api-key, x-timestamp, x-signature. Renseigner api_key et api_secret dans l'environnement avant utilisation.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "event": [
    {
      "listen": "prerequest",
      "script": {
        "type": "text/javascript",
        "exec": [
          "const apiKey = pm.environment.get('api_key') || pm.collectionVariables.get('api_key');",
          "const apiSecret = pm.environment.get('api_secret') || pm.collectionVariables.get('api_secret');",
          "const timestamp = Math.floor(Date.now() / 1000).toString();",
          "let rawBody = '';",
          "if (pm.request.body && pm.request.body.mode === 'raw') {",
          "  rawBody = pm.variables.replaceIn(pm.request.body.raw || '');",
          "}",
          "if (apiKey && apiSecret) {",
          "  const signature = CryptoJS.HmacSHA256(rawBody + timestamp, apiSecret).toString(CryptoJS.enc.Hex);",
          "  pm.request.headers.upsert({ key: 'x-api-key', value: apiKey });",
          "  pm.request.headers.upsert({ key: 'x-timestamp', value: timestamp });",
          "  pm.request.headers.upsert({ key: 'x-signature', value: signature });",
          "}",
          "if (pm.request.method === 'POST' && pm.request.url.toString().includes('/payments/request')) {",
          "  const key = pm.environment.get('idempotency_key') || pm.variables.replaceIn('ORDER-{{$timestamp}}');",
          "  pm.request.headers.upsert({ key: 'Idempotency-Key', value: key });",
          "}",
          "pm.request.headers.upsert({ key: 'Content-Type', value: 'application/json' });"
        ]
      }
    },
    {
      "listen": "test",
      "script": {
        "type": "text/javascript",
        "exec": [
          "pm.test('HTTP status is not 5xx', function () {",
          "  pm.expect(pm.response.code).to.be.below(500);",
          "});",
          "let json = {};",
          "try { json = pm.response.json(); } catch (e) {}",
          "if (json.reference) {",
          "  pm.environment.set('payment_reference', json.reference);",
          "}",
          "if (json.merchant_reference) {",
          "  pm.environment.set('last_merchant_reference', json.merchant_reference);",
          "}"
        ]
      }
    }
  ],
  "variable": [
    { "key": "base_url", "value": "https://sandbox-api.solimi.co" },
    { "key": "api_key", "value": "sk_test_xxx" },
    { "key": "api_secret", "value": "secret_xxx" }
  ],
  "item": [
    {
      "name": "01 - Health",
      "item": [
        {
          "name": "Health check",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/v1/health",
              "host": ["{{base_url}}"],
              "path": ["v1", "health"]
            },
            "description": "Verifie que l'API SOLIMI repond. Cette route peut etre appelee sans authentification."
          },
          "response": []
        }
      ]
    },
    {
      "name": "02 - Reference Data",
      "item": [
        {
          "name": "List payment methods",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/v1/payment-methods",
              "host": ["{{base_url}}"],
              "path": ["v1", "payment-methods"]
            },
            "description": "Retourne les moyens de paiement actifs. Requiert HMAC. Pour GET, la signature est calculee sur timestamp uniquement."
          },
          "response": []
        }
      ]
    },
    {
      "name": "03 - Payments",
      "item": [
        {
          "name": "Create payment - Mobile Money",
          "request": {
            "method": "POST",
            "header": [],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"merchant_reference\": \"{{merchant_reference}}\",\n  \"payment_type\": \"mobile_money\",\n  \"provider\": \"{{provider}}\",\n  \"amount\": {{amount}},\n  \"description\": \"Test paiement mobile money SOLIMI\",\n  \"customer_phone\": \"{{customer_phone}}\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/v1/payments/request",
              "host": ["{{base_url}}"],
              "path": ["v1", "payments", "request"]
            },
            "description": "Cree une demande de paiement Mobile Money. Champs requis: merchant_reference, payment_type=mobile_money, provider, amount, description, customer_phone. currency est facultatif et vaut XOF par defaut. Le script ajoute Idempotency-Key automatiquement."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Payment created', function () { pm.expect(pm.response.code).to.be.oneOf([200, 201]); });",
                  "const json = pm.response.json();",
                  "pm.expect(json).to.have.property('reference');",
                  "pm.environment.set('payment_reference', json.reference);"
                ]
              }
            }
          ],
          "response": []
        },
        {
          "name": "Create payment - SOLIMI Account",
          "request": {
            "method": "POST",
            "header": [],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"merchant_reference\": \"{{merchant_reference}}-ACCOUNT\",\n  \"payment_type\": \"solimi_account\",\n  \"account_id\": \"{{account_id}}\",\n  \"amount\": {{amount}},\n  \"description\": \"Test paiement compte SOLIMI\",\n  \"customer_phone\": \"{{customer_phone}}\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/v1/payments/request",
              "host": ["{{base_url}}"],
              "path": ["v1", "payments", "request"]
            },
            "description": "Cree une demande de paiement via compte SOLIMI. account_id doit respecter ^\\d{12}$. currency est facultatif et vaut XOF par defaut."
          },
          "response": []
        },
        {
          "name": "Create payment - SOLIMI Card",
          "request": {
            "method": "POST",
            "header": [],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"merchant_reference\": \"{{merchant_reference}}-CARD\",\n  \"payment_type\": \"solimi_card\",\n  \"card_id\": \"{{card_id}}\",\n  \"amount\": {{amount}},\n  \"description\": \"Test paiement carte SOLIMI\",\n  \"customer_phone\": \"{{customer_phone}}\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/v1/payments/request",
              "host": ["{{base_url}}"],
              "path": ["v1", "payments", "request"]
            },
            "description": "Cree une demande de paiement via carte SOLIMI. card_id doit respecter ^\\d{8}$. currency est facultatif et vaut XOF par defaut."
          },
          "response": []
        },
        {
          "name": "Get payment status",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/v1/payments/status/{{payment_reference}}",
              "host": ["{{base_url}}"],
              "path": ["v1", "payments", "status", "{{payment_reference}}"]
            },
            "description": "Consulte le statut courant d'un paiement. La variable payment_reference est automatiquement alimentee apres une creation de paiement."
          },
          "response": []
        }
      ]
    },
    {
      "name": "04 - Account",
      "item": [
        {
          "name": "Get account balance",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/v1/account/balance",
              "host": ["{{base_url}}"],
              "path": ["v1", "account", "balance"]
            },
            "description": "Retourne le solde disponible et reserve du partenaire."
          },
          "response": []
        }
      ]
    },
    {
      "name": "05 - Webhooks",
      "description": "La configuration webhook est effectuee par SOLIMI dans la plateforme interne. Le partenaire doit fournir webhook_url et webhook_secret, puis verifier les callbacks recus avec x-solimi-signature = webhook_secret.",
      "item": []
    },
    {
      "name": "06 - Negative Tests",
      "item": [
        {
          "name": "Create payment - invalid currency",
          "request": {
            "method": "POST",
            "header": [],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"merchant_reference\": \"{{merchant_reference}}-BAD-CURRENCY\",\n  \"payment_type\": \"mobile_money\",\n  \"provider\": \"{{provider}}\",\n  \"amount\": {{amount}},\n  \"currency\": \"EUR\",\n  \"description\": \"Test erreur devise\",\n  \"customer_phone\": \"{{customer_phone}}\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/v1/payments/request",
              "host": ["{{base_url}}"],
              "path": ["v1", "payments", "request"]
            },
            "description": "Cas de recette negatif: la devise doit etre XOF. Resultat attendu: erreur de validation."
          },
          "response": []
        },
        {
          "name": "Create payment - missing provider",
          "request": {
            "method": "POST",
            "header": [],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"merchant_reference\": \"{{merchant_reference}}-NO-PROVIDER\",\n  \"payment_type\": \"mobile_money\",\n  \"amount\": {{amount}},\n  \"description\": \"Test erreur provider manquant\",\n  \"customer_phone\": \"{{customer_phone}}\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/v1/payments/request",
              "host": ["{{base_url}}"],
              "path": ["v1", "payments", "request"]
            },
            "description": "Cas de recette negatif: provider est obligatoire pour mobile_money."
          },
          "response": []
        }
      ]
    }
  ]
}
