Guide

Symfony guide for calling the YKNPG flow from a controller.

Symfony guide for calling the YKNPG flow from a controller.

Prerequisites

  • PHP 8.1+, Composer, Symfony CLI optional.
  • .env.local storing YKNPG_API_TOKEN.
  1. Create project
  • composer create-project symfony/skeleton demo-symfony
  • cd demo-symfony
  • composer require symfony/http-client symfony/framework-bundle symfony/runtime symfony/console
  1. Configure environment
  • File: .env.local
YKNPG_API_TOKEN=replace-with-your-token
YKNPG_BASE_URL=https://yknpg.ngoul.com/api/v1
  1. Create controller
  • File: src/Controller/PaymentController.php
<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\HttpClient\HttpClientInterface;

class PaymentController extends AbstractController
{
    #[Route('/pay', name: 'app_pay', methods: ['POST'])]
    public function pay(Request $request, HttpClientInterface $client): JsonResponse
    {
        $data = json_decode($request->getContent(), true) ?? [];
        if (!isset($data['phone'], $data['amount'])) {
            return $this->json(['error' => 'phone and amount required'], 400);
        }

        $token = $_ENV['YKNPG_API_TOKEN'];
        $base = $_ENV['YKNPG_BASE_URL'] ?? 'https://yknpg.ngoul.com/api/v1';
        $http = $client->withOptions([
            'base_uri' => $base,
            'headers' => ['Authorization' => "Bearer $token"],
            'timeout' => 10,
        ]);

        $payload = [
            'amount' => (int) $data['amount'],
            'provider' => 'ORANGE_MONEY',
            'user_infos' => ['number' => $data['phone']],
            'callback_url' => 'http://example.com',
            'callback_method' => 'POST',
            'your_message' => 'pay this',
            'your_order_ref' => 'demo-1',
            'provider_fees_on_customer' => true,
        ];

        $created = $http->request('POST', '/transactions/', ['json' => $payload])->toArray();
        $paid = $http->request('POST', "/transactions/{$created['uuid']}/pay/")->toArray();

        $status = $paid['status'] ?? 'new';
        while (in_array($status, ['new', 'paying'])) {
            sleep(5);
            $resp = $http->request('GET', "/transactions/{$created['uuid']}/")->toArray();
            $status = $resp['status'] ?? $status;
        }

        return $this->json([
            'instructions' => $created['instructions'] ?? null,
            'post_pay_instructions' => $paid['instructions'] ?? null,
            'final_status' => $status,
        ]);
    }
}
  1. Register route
  • File: config/routes.yaml
app_pay:
  path: /pay
  controller: App\Controller\PaymentController::pay
  methods: [POST]
  1. Run
  • symfony serve -d or php -S 127.0.0.1:8000 -t public
  • POST {"phone": "...", "amount": 1000} to http://127.0.0.1:8000/pay.

Notes

  • Keep the token out of the browser; reuse the controller logic in messengers/queues if needed.