#Client guide
nagad-client is a small, headless state machine with bindings. It never holds secrets and never decides a payment: your server does. It does not render UI.
#The contract
- Your backend
/createreturnscallBackUrl(the hosted Nagad page). initiate(url)sends the customer there (stateredirecting).- When the customer returns, call
handleCallback(params). The state becomesverifying, notsuccess.onCallbackfires. - Ask your server to verify (your
/callbackroute or an API call). Then callconfirmSuccess()or, if the server could not tell,confirmPending(). onSuccessfires only fromconfirmSuccess().
#Vanilla
import { createNagadCheckout } from 'nagad-client';
const checkout = createNagadCheckout({
onCallback: async ({ paymentRefId }) => {
const r = await fetch(`/api/nagad/callback?payment_ref_id=${paymentRefId}`).then((x) => x.json());
r.success ? checkout.confirmSuccess() : checkout.confirmPending();
},
onSuccess: ({ orderId }) => showReceipt(orderId),
});
checkout.initiate(callBackUrl);
// on return: checkout.handleCallback(location.search);
#React
import { useNagadCheckout } from 'nagad-client/react';
const { state, isLoading, isSuccess, isPending, initiate, handleCallback, confirmSuccess, confirmPending } =
useNagadCheckout({ onCallback: verifyOnServer });
#React Native
import { WebView } from 'react-native-webview';
import { createWebViewNavigationHandler } from 'nagad-client/react-native';
const nav = createWebViewNavigationHandler({
callbackUrl: 'https://shop.example/api/nagad/callback',
allowedHosts: ['nagad.com.bd', 'mynagad.com'], // hosts Nagad told you to expect
onCallback: verifyOnServer,
onClose: () => navigation.goBack(),
});
<WebView
source={{ uri: paymentUrl }}
onShouldStartLoadWithRequest={nav.onShouldStartLoadWithRequest}
onNavigationStateChange={nav.onNavigationStateChange}
/>
- The handler stops the WebView from loading your callback URL and blocks navigation to hosts outside
allowedHosts(a basic phishing guard). - Android back button:
nav.handleHardwareBackPress(canGoBack, webViewRef)goes back in the WebView if it can, otherwise callsonClose. Wire it toBackHandler. - Status: experimental. Not tested on physical devices.
#Vue, Svelte, Angular
import { useNagad } from 'nagad-client/vue'; // returns machine + functions
import { createNagadStore } from 'nagad-client/svelte'; // subscribe-able store
import { NagadService } from 'nagad-client/angular'; // plain service; extend and decorate it with @Injectable()
All expose initiate, handleCallback, confirmSuccess, confirmPending, reset and the state.
#Styling
Headless only. Slot-based and themed components are not available in this release.