Requirements
| Starter | Spring Boot | Java |
|---|---|---|
nepal-pay-spring-boot-3-starter |
3.2.x or higher | 17 or higher |
nepal-pay-spring-boot-4-starter |
4.0.x or higher | 21 or higher |
Install
Step 1 โ Add JitPack repository to pom.xml:
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
Step 2 โ Add dependency for your Spring Boot version:
Spring Boot 3.2+ (Java 17+):
<dependency>
<groupId>com.github.sujankim.nepal-pay-spring-boot-starter</groupId>
<artifactId>nepal-pay-spring-boot-3-starter</artifactId>
<version>v0.5.0</version>
</dependency>
Spring Boot 4.x (Java 21+):
<dependency>
<groupId>com.github.sujankim.nepal-pay-spring-boot-starter</groupId>
<artifactId>nepal-pay-spring-boot-4-starter</artifactId>
<version>v0.5.0</version>
</dependency>
Step 1 โ Add JitPack to settings.gradle:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
Step 2 โ Add to build.gradle:
Spring Boot 3.2+:
dependencies {
implementation 'com.github.sujankim.nepal-pay-spring-boot-starter:nepal-pay-spring-boot-3-starter:v0.5.0'
}
Spring Boot 4.x:
dependencies {
implementation 'com.github.sujankim.nepal-pay-spring-boot-starter:nepal-pay-spring-boot-4-starter:v0.5.0'
}
Step 1 โ Add JitPack to settings.gradle.kts:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
mavenCentral()
maven { url = uri("https://jitpack.io") }
}
}
Step 2 โ Add to build.gradle.kts:
Spring Boot 3.2+:
dependencies {
implementation("com.github.sujankim.nepal-pay-spring-boot-starter:nepal-pay-spring-boot-3-starter:v0.5.0")
}
Spring Boot 4.x:
dependencies {
implementation("com.github.sujankim.nepal-pay-spring-boot-starter:nepal-pay-spring-boot-4-starter:v0.5.0")
}
Configure
Add to application.yml:
nepalpay:
khalti:
secret-key: ${KHALTI_SECRET_KEY}
return-url: ${KHALTI_RETURN_URL}
website-url: ${YOUR_WEBSITE_URL}
sandbox: true
esewa:
secret-key: ${ESEWA_SECRET_KEY}
product-code: ${ESEWA_PRODUCT_CODE}
success-url: ${ESEWA_SUCCESS_URL}
failure-url: ${ESEWA_FAILURE_URL}
sandbox: true
fonepay:
merchant-code: ${FONEPAY_MERCHANT_CODE}
secret-key: ${FONEPAY_SECRET_KEY}
return-url: ${FONEPAY_RETURN_URL}
sandbox: true
connectips:
merchant-id: ${CONNECTIPS_MERCHANT_ID}
app-id: ${CONNECTIPS_APP_ID}
app-name: ${CONNECTIPS_APP_NAME}
app-password: ${CONNECTIPS_APP_PASSWORD}
pfx-path: ${CONNECTIPS_PFX_PATH}
pfx-password: ${CONNECTIPS_PFX_PASSWORD}
sandbox: true
That is all. Spring Boot auto-configures the client beans
automatically when keys are present. No @EnableNepalPay,
no @Bean method, no config class.
Khalti Quickstart
@Service
@RequiredArgsConstructor
public class PaymentService {
private final KhaltiClient khaltiClient; // โ auto-injected
// Step 1: Initiate
public String startKhalti(String orderId, long amountNPR) {
var res = khaltiClient.initiatePayment(
KhaltiInitiateRequest.builder()
.amount(amountNPR * 100L) // NPR โ paisa
.purchaseOrderId(orderId)
.purchaseOrderName("Your Product")
.build()
);
// IMPORTANT: save res.pidx() to DB before returning!
return res.paymentUrl(); // redirect user here
}
// Step 2: Verify after callback
public boolean verifyKhalti(String pidx) {
return khaltiClient.lookupPayment(pidx).isPaymentSuccessful();
}
}
See the full Khalti guide โ
eSewa Quickstart
@Service
@RequiredArgsConstructor
public class PaymentService {
private final EsewaClient esewaClient; // โ auto-injected
// Step 1: Build signed form payload
public EsewaFormPayload startEsewa(BigDecimal amountNPR) {
String uuid = EsewaClient.generateTransactionUuid();
// IMPORTANT: save uuid to DB before returning!
return esewaClient.buildFormPayload(amountNPR, uuid);
// Frontend POSTs form fields to payload.formActionUrl()
}
// Step 2: Verify after callback
public boolean verifyEsewa(String encodedData) {
return esewaClient.verifyCallback(encodedData).isPaymentSuccessful();
}
}
See the full eSewa guide โ
Fonepay Quickstart
@Service
@RequiredArgsConstructor
public class PaymentService {
private final FonepayClient fonepayClient; // โ auto-injected
// Step 1: Build signed redirect URL
public String startFonepay(String orderId, double amountNPR) {
String prn = "FP-" + orderId;
// IMPORTANT: save prn to DB before returning!
FonepayRedirectParams params = fonepayClient.buildRedirectParams(
FonepayPaymentRequest.builder()
.prn(prn)
.amount(amountNPR) // NPR directly โ not paisa!
.remarks1("Your Product")
.build()
);
return params.redirectUrl(); // redirect user here
}
// Step 2: Verify after callback
public boolean verifyFonepay(FonepayCallbackResponse callback) {
return fonepayClient.verifyCallback(callback).isPaymentSuccessful();
}
}
See the full Fonepay guide โ
ConnectIPS Quickstart
// Step 1: Build RSA-signed form payload
ConnectIpsFormPayload payload = connectIpsClient.buildFormPayload(
ConnectIpsPaymentRequest.builder()
.txnId("TXN-" + orderId)
.amountNPR(100L) // auto-converts to paisa
.referenceId(orderId)
.build()
);
// Frontend POSTs form to payload.formActionUrl()
// Step 2: Validate after callback
ConnectIpsValidateResponse res =
connectIpsClient.validateTransaction(txnId, referenceId, txnAmtPaisa);
if (res.isPaymentSuccessful()) { /* mark as paid */ }
See the full ConnectIPS guide โ
Sandbox Credentials
eSewa Sandbox
| Field | Value |
|---|---|
| eSewa ID | 9806800001 |
| Password | Nepal@123 |
| MPIN | 1122 |
| Token | 123456 |
| Secret Key | 8gBm/:&EnhH.1/q |
| Product Code | EPAYTEST |
Khalti Sandbox
Get your test secret key from test-admin.khalti.com.
Fonepay Sandbox
Sandbox URL: https://dev.fonepay.com/api/merchantRequest
Merchant code and secret key are provided after registration with Fonepay.
Amount Units Per Gateway
This is the most common source of confusion. Each gateway uses different units.