Guide
Vue.js guide to initiate the YKNPG transaction flow (Vite).
Vue.js guide to initiate the YKNPG transaction flow (Vite).
Security note
- Keep the bearer token on a backend in production. Using
.env.localin the browser is for local testing only.
Prerequisites
- Node.js 18+, npm.
- Create app
npm create vite@latest demo-vue -- --template vuecd demo-vue && npm installnpm install axios
- Add environment
- File:
.env.local
VITE_YKNPG_API_TOKEN=replace-with-your-token
VITE_YKNPG_BASE_URL=https://yknpg.ngoul.com/api/v1
- Add helper
- File:
src/api.js
import axios from "axios";
const client = axios.create({
baseURL: import.meta.env.VITE_YKNPG_BASE_URL || "https://yknpg.ngoul.com/api/v1",
headers: { Authorization: `Bearer ${import.meta.env.VITE_YKNPG_API_TOKEN}` },
timeout: 10000,
});
export async function startTransaction(amount, phone) {
const payload = {
amount,
provider: "ORANGE_MONEY",
user_infos: { number: phone },
callback_url: "http://example.com",
callback_method: "POST",
your_message: "pay this",
your_order_ref: "demo-1",
provider_fees_on_customer: true,
};
const { data: created } = await client.post("/transactions/", payload);
const { data: paid } = await client.post(`/transactions/${created.uuid}/pay/`);
let status = paid.status;
while (status === "new" || status === "paying") {
await new Promise((r) => setTimeout(r, 5000));
const { data } = await client.get(`/transactions/${created.uuid}/`);
status = data.status;
}
return { created, paid, finalStatus: status };
}
- Update component
- File:
src/App.vue
<template>
<main class="wrap">
<h1>Start payment</h1>
<form @submit.prevent="submit">
<label>Phone</label>
<input v-model="phone" required />
<label>Amount</label>
<input type="number" v-model.number="amount" min="1" required />
<button :disabled="loading">{{ loading ? "Processing..." : "Pay" }}</button>
</form>
<p v-if="error" class="error">{{ error }}</p>
<section v-if="result">
<p>Gateway instructions: {{ result.created.instructions }}</p>
<p>Post-pay instructions: {{ result.paid.instructions }}</p>
<p>Final status: {{ result.finalStatus }}</p>
</section>
</main>
</template>
<script setup>
import { ref } from "vue";
import { startTransaction } from "./api";
const phone = ref("");
const amount = ref(1000);
const loading = ref(false);
const error = ref("");
const result = ref(null);
const submit = async () => {
loading.value = true;
error.value = "";
try {
result.value = await startTransaction(Number(amount.value), phone.value);
} catch (e) {
error.value = e.response?.data || e.message;
} finally {
loading.value = false;
}
};
</script>
<style>
.wrap { max-width: 480px; margin: 2rem auto; font-family: sans-serif; }
.error { color: red; }
</style>
- Run
npm run dev- Open the local URL.
Notes
- Move the token to a backend proxy for production use.