curl -X POST https://api.paybridgenp.com/v1/checkout/cs_01j9x2k3m4n5p6q7r8s9t0u1v2/expire \
-H "Authorization: Bearer sk_test_your_key"import { PayBridgeNP } from "@paybridge-np/sdk";
const paybridgenp = new PayBridgeNP({ apiKey: "sk_test_your_key" });
await paybridgenp.checkout.expire("cs_01j9x2k3m4n5p6q7r8s9t0u1v2");$paybridgenp->expireCheckoutSession('cs_01j9x2k3m4n5p6q7r8s9t0u1v2');import requests
url = "https://api.paybridgenp.com/v1/checkout/{id}/expire"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text)package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.paybridgenp.com/v1/checkout/{id}/expire"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.paybridgenp.com/v1/checkout/{id}/expire")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.paybridgenp.com/v1/checkout/{id}/expire")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"id": "cs_01j9x2k3m4n5p6q7r8s9t0u1v2",
"status": "expired",
"flow": "hosted",
"provider": null,
"expires_at": "2026-03-30T14:30:00.000Z"
}{
"error": {
"message": "<string>",
"type": "authentication_error",
"code": "<string>",
"request_id": "req_2Je91NlWKuXkdXUJOK9gaHNW",
"detail": "<string>",
"refund": {
"id": "ref_01j9x2k3m4n5p6q7r8s9t0u1v2",
"livemode": true,
"paymentId": "pay_01j9x2k3m4n5p6q7r8s9t0u1v2",
"projectId": "<string>",
"mode": "sandbox",
"amount": 10000,
"currency": "NPR",
"reason": "customer_request",
"status": "processing",
"providerRefundId": "<string>",
"failureReason": "<string>",
"notes": "<string>",
"mobileNumber": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z"
},
"suspension": {
"suspended_at": "2023-11-07T05:31:56Z",
"reason": "<string>"
},
"pause": {
"paused_at": "2023-11-07T05:31:56Z",
"reason": "<string>"
}
}
}{
"error": {
"message": "<string>",
"type": "authentication_error",
"code": "<string>",
"request_id": "req_2Je91NlWKuXkdXUJOK9gaHNW",
"detail": "<string>",
"refund": {
"id": "ref_01j9x2k3m4n5p6q7r8s9t0u1v2",
"livemode": true,
"paymentId": "pay_01j9x2k3m4n5p6q7r8s9t0u1v2",
"projectId": "<string>",
"mode": "sandbox",
"amount": 10000,
"currency": "NPR",
"reason": "customer_request",
"status": "processing",
"providerRefundId": "<string>",
"failureReason": "<string>",
"notes": "<string>",
"mobileNumber": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z"
},
"suspension": {
"suspended_at": "2023-11-07T05:31:56Z",
"reason": "<string>"
},
"pause": {
"paused_at": "2023-11-07T05:31:56Z",
"reason": "<string>"
}
}
}{
"error": {
"message": "eSewa has not confirmed that this Intent booking is cancelled. Retry shortly before creating another payable session.",
"type": "invalid_request_error",
"code": "provider_cancel_unconfirmed",
"request_id": "req_2Je91NlWKuXkdXUJOK9gaHNW"
}
}Expire a checkout session
Marks a checkout session as expired so it can no longer accept payment.
Use this when you mint a fresh checkout session for a logical purchase that already had one outstanding (for example, a customer requested a new payment link after the original expired). Without explicitly expiring the old session, its URL remains payable until the session’s natural 30-minute TTL elapses, which can let a customer who reloads the old tab pay twice.
Idempotent. Calling expire on a session that is already in a terminal state (success, failed, cancelled, expired) returns 200 with the current status - no error. Only pending and initiated sessions are flipped. A failed or cancelled session keeps its status, but its expires_at is moved to now so the customer can no longer retry or pay it. If the customer starts an eSewa Intent payment on the session while the call runs, it returns 409 with code: "session_changed"; retry the call.
If the session has an active eSewa Intent booking, PayBridgeNP first confirms that booking is paid or dead at eSewa. When eSewa cannot confirm cancellation, the call returns 409 with code: "provider_cancel_unconfirmed" and leaves the session observed; retry before minting another payable session.
Shopify order cancellation. Pass for_order_cancellation=true to request order-wide closure instead of ordinary session expiry. Returns { id, safe_to_cancel }. Only an explicit true permits order cancellation: all related sessions in the same project, mode and shop are closed, with no unresolved or captured provider attempts. Browser cancellation and local expiry are not evidence that a provider attempt is dead. Uncertainty returns false; wait for verified provider reconciliation or manual review. Stop issuing sessions for the order before using this option. Ordinary expiry responses do not authorize order cancellation.
Retire only an untouched session. Pass only_if_untouched=true when you are about to replace a session and must never end one a customer is already paying. The session is expired only if it is still pending with no payment method chosen. Otherwise it is left unchanged and returned with its real status: hand that session back instead of creating another. The response then includes only_if_untouched: true, so you can tell that the option was honoured.
curl -X POST https://api.paybridgenp.com/v1/checkout/cs_01j9x2k3m4n5p6q7r8s9t0u1v2/expire \
-H "Authorization: Bearer sk_test_your_key"import { PayBridgeNP } from "@paybridge-np/sdk";
const paybridgenp = new PayBridgeNP({ apiKey: "sk_test_your_key" });
await paybridgenp.checkout.expire("cs_01j9x2k3m4n5p6q7r8s9t0u1v2");$paybridgenp->expireCheckoutSession('cs_01j9x2k3m4n5p6q7r8s9t0u1v2');import requests
url = "https://api.paybridgenp.com/v1/checkout/{id}/expire"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text)package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.paybridgenp.com/v1/checkout/{id}/expire"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.paybridgenp.com/v1/checkout/{id}/expire")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.paybridgenp.com/v1/checkout/{id}/expire")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"id": "cs_01j9x2k3m4n5p6q7r8s9t0u1v2",
"status": "expired",
"flow": "hosted",
"provider": null,
"expires_at": "2026-03-30T14:30:00.000Z"
}{
"error": {
"message": "<string>",
"type": "authentication_error",
"code": "<string>",
"request_id": "req_2Je91NlWKuXkdXUJOK9gaHNW",
"detail": "<string>",
"refund": {
"id": "ref_01j9x2k3m4n5p6q7r8s9t0u1v2",
"livemode": true,
"paymentId": "pay_01j9x2k3m4n5p6q7r8s9t0u1v2",
"projectId": "<string>",
"mode": "sandbox",
"amount": 10000,
"currency": "NPR",
"reason": "customer_request",
"status": "processing",
"providerRefundId": "<string>",
"failureReason": "<string>",
"notes": "<string>",
"mobileNumber": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z"
},
"suspension": {
"suspended_at": "2023-11-07T05:31:56Z",
"reason": "<string>"
},
"pause": {
"paused_at": "2023-11-07T05:31:56Z",
"reason": "<string>"
}
}
}{
"error": {
"message": "<string>",
"type": "authentication_error",
"code": "<string>",
"request_id": "req_2Je91NlWKuXkdXUJOK9gaHNW",
"detail": "<string>",
"refund": {
"id": "ref_01j9x2k3m4n5p6q7r8s9t0u1v2",
"livemode": true,
"paymentId": "pay_01j9x2k3m4n5p6q7r8s9t0u1v2",
"projectId": "<string>",
"mode": "sandbox",
"amount": 10000,
"currency": "NPR",
"reason": "customer_request",
"status": "processing",
"providerRefundId": "<string>",
"failureReason": "<string>",
"notes": "<string>",
"mobileNumber": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z"
},
"suspension": {
"suspended_at": "2023-11-07T05:31:56Z",
"reason": "<string>"
},
"pause": {
"paused_at": "2023-11-07T05:31:56Z",
"reason": "<string>"
}
}
}{
"error": {
"message": "eSewa has not confirmed that this Intent booking is cancelled. Retry shortly before creating another payable session.",
"type": "invalid_request_error",
"code": "provider_cancel_unconfirmed",
"request_id": "req_2Je91NlWKuXkdXUJOK9gaHNW"
}
}?for_order_cancellation=true. Only safe_to_cancel: true confirms closure of
related sessions and verified-dead provider attempts. A false or missing value
means defer cancellation until provider reconciliation or manual review.Authorizations
Query Parameters
Response
Session expired (or already terminal), or order-closure verdict when requested.
Was this page helpful?