Guide

Integrate YKNPG payment in a C application

C guide for creating and paying a YKNPG transaction (libcurl).

Prerequisites

  • GCC/Clang, libcurl development headers.
  • Environment variables YKNPG_API_TOKEN and optionally YKNPG_BASE_URL.
  1. Create project folder
  • mkdir -p demo_c && cd demo_c
  1. Write helper program
  • File: transaction.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>

struct memory {
    char *response;
    size_t size;
};

static size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp) {
    size_t realsize = size * nmemb;
    struct memory *mem = (struct memory *)userp;
    mem->response = realloc(mem->response, mem->size + realsize + 1);
    memcpy(&(mem->response[mem->size]), contents, realsize);
    mem->size += realsize;
    mem->response[mem->size] = 0;
    return realsize;
}

static char *base_url() {
    char *env = getenv("YKNPG_BASE_URL");
    return env ? env : "https://yknpg.ngoul.com/api/v1";
}

static CURL *init_curl(struct curl_slist **headers) {
    CURL *curl = curl_easy_init();
    char auth[512];
    snprintf(auth, sizeof(auth), "Authorization: Bearer %s", getenv("YKNPG_API_TOKEN"));
    *headers = curl_slist_append(*headers, "Content-Type: application/json");
    *headers = curl_slist_append(*headers, auth);
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, *headers);
    return curl;
}

int main(int argc, char **argv) {
    if (argc < 3) {
        fprintf(stderr, "Usage: ./transaction <phone> <amount>\n");
        return 1;
    }
    curl_global_init(CURL_GLOBAL_DEFAULT);

    const char *phone = argv[1];
    const char *amount = argv[2];

    struct curl_slist *headers = NULL;
    CURL *curl = init_curl(&headers);
    struct memory chunk = {0};

    char url[256];
    snprintf(url, sizeof(url), "%s/transactions/", base_url());
    const char *payload_template = "{\"amount\":%s,\"provider\":\"ORANGE_MONEY\",\"user_infos\":{\"number\":\"%s\"},\"callback_url\":\"http://example.com\",\"callback_method\":\"POST\",\"your_message\":\"pay this\",\"your_order_ref\":\"demo-1\",\"provider_fees_on_customer\":true}";
    char payload[512];
    snprintf(payload, sizeof(payload), payload_template, amount, phone);

    curl_easy_setopt(curl, CURLOPT_URL, url);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);

    CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK) {
        fprintf(stderr, "Create failed: %s\n", curl_easy_strerror(res));
        return 1;
    }
    printf("Transaction response: %s\n", chunk.response);
    curl_slist_free_all(headers);
    curl_easy_cleanup(curl);
    curl_global_cleanup();
    free(chunk.response);
    return 0;
}
  1. Build
  • gcc transaction.c -o transaction -lcurl
  1. Run
  • YKNPG_API_TOKEN=token ./transaction <phone> <amount>

Notes

  • For brevity this example prints the create response only; expand with additional libcurl calls for /pay/ and status polling following the same pattern (POST then GET until status exits new/paying).
  • Keep JSON small to avoid manual string mistakes; for production use a JSON library (cJSON).