5
Verifying Payment Status

After payment completion or when a customer returns to your application, you may need to verify the payment status in your database to show the appropriate confirmation or error page.

Payment Verification Implementation

Implement a payment verification function to check the status:

Server-side payment status lookup
export async function verifyPayment(sessionToken: string) {
  const response = await fetch(
    "https://api.saligpay.com/api/checkout/session/" + sessionToken,
    { headers: { Authorization: "Bearer " + await getAccessToken() } },
  );

  if (!response.ok) throw new Error("Unable to verify payment");
  return response.json();
}

Payment Status Handling

Here's how to handle different payment statuses:

COMPLETED

Payment has settled successfully.

Handling:

  • Mark order as paid.
  • Provision goods or grant access.

PENDING

Payment is awaiting confirmation.

Handling:

  • Show pending state to user.
  • Continue to rely on webhook updates.

FAILED

Payment did not complete.

Handling:

  • Surface retry action to user.
  • Log failure reason for support diagnostics.

Direct API Verification

Alternatively, you can verify payment status directly with the SaligPay API:

Verification endpoint call
curl -H "Authorization: Bearer <ACCESS_TOKEN>" \
  "https://api.saligpay.com/api/checkout/session/<SESSION_TOKEN>"

Best Practice: Always verify payment status on your server before providing access to purchased goods or services. Relying solely on client-side verification is not secure as it could be manipulated.

Displaying Payment Result

In your return page component, display appropriate messages based on the payment status:

Return/Result Page Component
import { useLoaderData, Link } from "react-router";

export default function PaymentReturn() {
  const { success, payment, status, message } = useLoaderData();
  
  if (!success) {
    return (
      <div className="error-container">
        <h2>Payment Verification Failed</h2>
        <p>{message || "Unable to verify payment status"}</p>
        <Link to="/">Return to Home</Link>
      </div>
    );
  }
  
  // Render based on payment status
  return (
    <div className="payment-result">
      <h2>Payment {payment.status}</h2>
      <p>{payment.message}</p>
      
      {payment.status === "COMPLETED" && (
        <div className="success-details">
          <p>Thank you for your payment!</p>
          <p>Transaction ID: {payment.details.transactionId}</p>
          <p>Amount: {"$" + (payment.amount / 100).toFixed(2)}</p>
        </div>
      )}
      
      {payment.status === "FAILED" && (
        <div className="failure-details">
          <p>We encountered an issue with your payment:</p>
          <p>{payment.details.reason}</p>
          <Link to="/payment" className="retry-button">
            Try Again
          </Link>
        </div>
      )}
      
      <Link to="/">Return to Home</Link>
    </div>
  );
}