---
agentTools:
  projectIndex: https://docs.xpresspayonline.com/llms.txt
---

# Re-query Payment

Re-query the payment with xpresspay.

After the user has successfully paid, you need to verify that the payment was successful with Xpresspay before giving value to your customer on your website.

Although the Xpresspay inline already verifies the payment from the client side, we strongly recommend you still do a server-side verification to be double sure no foul play occurred during the payment flow.

Below are the important things to check for when validating the payment:

Verify the `transaction reference`.

Verify the `data.paymentResponseCode` of the transaction to be `successful(000)`.

Verify the `currency` to be the expected currency

Most importantly validate the `amount` paid to be equal to or at least greater than the amount of the value to be given.

Below are sample code snippets showing how to implement server-side validation in different programming languages

[block:callout]
{
  "type": "warning",
  "title": "Replace the url when pointing live to https://api.xpresspayonline.com/v1/payments/query",
  "body": "Replace when pointing to live from\nhttps://xpresspayonlineapisandbox.xpresspayments.com/v1/payments/query\nto\nhttps://api.xpresspayonline.com/v1/payments/query"
}
[/block]

[block:code]
{
  "codes": [
    {
      "code": "curl --request POST \\\n  --url https://xpresspayonlineapisandbox.xpresspayments.com/v1/payments/query \\\n  --header 'content-type: application/json' \\\n  --data '{\"publicKey\": \"<YOUR PUBLIC KEY>\", \"transactionId\": \"<YOUR TRANSACTION ID>\"}'",
      "language": "curl"
    },
    {
      "code": "<?php\n\n$result = array();\n\n$postdata =  array(\n  'publicKey' => 'XPPUBK-ead4d14d9ded04aer5d5b63a0a06d2f-X',\n  'transactionId' => 'MXX-ASC-4578'\n  );\n\n$ch = curl_init();\ncurl_setopt($ch, CURLOPT_URL,\"https://xpresspayonlineapisandbox.xpresspayments.com/v1/payments/query\");\ncurl_setopt($ch, CURLOPT_POST, 1);\ncurl_setopt($ch, CURLOPT_POSTFIELDS,json_encode($postdata));  //Post Fields\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n\n$headers = [\n  'Content-Type: application/json',\n];\n\ncurl_setopt($ch, CURLOPT_HTTPHEADER, $headers);\n\n$request = curl_exec ($ch);\n$err = curl_error($ch);\n\nif($err){\n    // there was an error contacting xpresspayonline\n  die('Curl returned error: ' . $err);\n}\n\n\ncurl_close ($ch);\n\n$result = json_decode($request, true);\n\nif('null' != $result->error){\n  // there was an error from the API\n  die('API returned error: ' . $result->message);\n}\n\nif('000' == $result->data->payment->paymentResponseCode){\n  // transaction was successful...\n  // please check other things like whether you already gave value for this ref\n  // If the amount and currency matches the expected amount and currency etc.\n  // if the email matches the customer who owns the product etc\n  // Give value\n}",
      "language": "php"
    },
    {
      "code": "//Endpoint to verify transaction\n    private final String REQUERY_ENDPOINT = \"https://xpresspayonlineapisandbox.xpresspayments.com/v1/payments/query\";\n\n    /**\n     *\n     * Method to\n     *\n     * @param paymententity - <b>paymententity - set as a constant with default value as 1</b>\n     * @param transactionId - <b>transactionId - is the unique payment reference generated by the merchant.</b>\n     * @param publicKey - <b>publicKey - is the merchant public key</b>\n     * @param paymentType - <b>PaymentType - is the transaction payment type (CARD/ACCOUNT/QR/USSD/WALLET)</b>\n     * @return\n     * @throws UnirestException\n     */\n    public JSONObject verify(String transactionId, String publicKey, double amount, String paymentType) throws UnirestException, Exception {\n\n        // This packages the payload\n        JSONObject data = new JSONObject();\n        data.put(\"transactionId\", transactionId);\n        data.put(\"publicKey\", publicKey)\n\n        // end of payload\n\n        // This sends the request to server with payload\n        HttpResponse<JsonNode> response = Unirest.post(REQUERY_ENDPOINT)\n                .header(\"Content-Type\", \"application/json\")\n                .body(data)\n                .asJson();\n\n        // This get the response from payload\n        JsonNode jsonNode = response.getBody();\n\n        // This get the json object from payload\n        JSONObject responseObject = jsonNode.getObject();\n\n        // check of no object is returned\n        if(responseObject == null)\n            throw new Exception(\"No response from server\");\n\n        // This get status from returned payload\n        String status = responseObject.optString(\"status\", null);\n        String error = responseObject.optString(\"error\", null);\n\n        // this ensures that status is not null\n        if(status == null)\n            throw new Exception(\"Transaction status unknown\");\n\n        // This confirms the transaction exist on xpresspayonline\n        if(!\"null\".equalsIgnoreCase(error)){\n\n            String message = responseObject.optString(\"message\", null);\n\n            throw new Exception(message);\n        }\n\n        data = responseObject.getJSONObject(\"data\");\n\n        // This get the amount stored on server\n        double actualAmount = data.getDouble(\"amount\");\n\n        // This validates that the amount stored on client is same returned\n        if(actualAmount != amount)\n            throw new Exception(\"Amount does not match\");\n\n\n        // now you can give value for payment.\n\n    }",
      "language": "java"
    },
    {
      "code": "var data = new {transactionId = \"MXX-ASC-4578\", publicKey = \"XPPUBK-e6db11d1f8a6208de8cb2f94e293450e-X\"};\n            var client = new HttpClient();\n            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(\"application/json\"));\n            var responseMessage = client.PostAsJsonAsync(\"https://xpresspayonlineapisandbox.xpresspayments.com/v1/payments/query\", data).Result;\n            var responseStr = responseMessage.Content.ReadAsStringAsync().Result;\n            var response = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponseData>(responseStr);\n            if (response.data.payment.paymentResponseCode == \"000\" && response.data.amount == amount )\n            {\n\n              System.Console.WriteLine(\"Payment Successful then give value\");\n\n            }",
      "language": "csharp"
    }
  ]
}
[/block]

[block:api-header]
{
  "title": "Re-query Payment Response"
}
[/block]

[block:code]
{
  "codes": [
    {
      "code": "{\n    \"status\": \"SUCCESS\",\n    \"data\": {\n        \"payment\": {\n            \"paymentResponseCode\": \"000\",\n            \"paymentResponseMessage\": \"successful\",\n            \"uniqueKey\": \"6ce13c57aa\",\n            \"transactionId\": \"null-MXX1-QR-4578\",\n            \"deviceFingerPrint\": \"69e6b7f0sb72037aa8428b70fbe03986c\",\n            \"cycle\": \"one-time\",\n            \"amount\": \"300\",\n            \"currency\": \"NGN\",\n            \"chargedAmount\": \"300\",\n            \"appFee\": \"4.2\",\n            \"merchantFee\": \"0\",\n            \"merchantBearsFee\": \"1\",\n            \"chargeCode\": \"00\",\n            \"chargeMessage\": \"QR GENERATED. PENDING VALIDATION\",\n            \"authModel\": \"MVISA-QR\",\n            \"ip\": \"103.238.105.185\",\n            \"narration\": \"Xpress Payments\",\n            \"status\": \"successful\",\n            \"vbvCode\": \"N/A\",\n            \"vbvMessage\": \"N/A\",\n            \"authUrl\": \"NO-URL\",\n            \"accountCode\": \"00\",\n            \"accountMessage\": \"successful\",\n            \"paymentType\": \"mvisa-qr\",\n            \"paymentId\": \"118\",\n            \"fraudStatus\": \"ok\",\n            \"chargeType\": \"normal\",\n            \"createdDay\": \"1\",\n            \"createdDayName\": \"MONDAY\",\n            \"createdWeek\": \"5\",\n            \"createdMonth\": \"0\",\n            \"createdMonthName\": \"JANUARY\",\n            \"createdQuarter\": \"1\",\n            \"createdYear\": \"2019\",\n            \"createdYearIsLeap\": \"false\",\n            \"createdDayIsPublicHoliday\": \"0\",\n            \"createdHour\": \"11\",\n            \"createdMinute\": \"8\",\n            \"createdPmAm\": \"am\",\n            \"created\": null,\n            \"customerId\": \"79997\",\n            \"customerPhone\": \"090882232\",\n            \"customerNetworkProvider\": \"UNKNOWN PROVIDER\",\n            \"customerName\": \"Ade Test\",\n            \"customerEmail\": \"tester@xpresspayment.com\",\n            \"customerEmailProvider\": \"COMPANY EMAIL\",\n            \"customerCreated\": \"2019-01-28T10:48:51.000Z\",\n            \"accountId\": \"509\",\n            \"accountBusinessName\": \"Xpress Payments\",\n            \"accountContactPerson\": \"Taofeek Gidado\",\n            \"accountCountry\": \"NG\",\n            \"accountBearsFeeAtTransactionTime\": \"1\",\n            \"accountParent\": \"1\",\n            \"accountVpcMerchant\": \"N/A\",\n            \"accountAlias\": null,\n            \"accountIsLiveApproved\": \"0\",\n            \"orderReference\": \"RV46FDC384C30FE0\",\n            \"paymentPlan\": null,\n            \"paymentPage\": null,\n            \"accountNumber\": null,\n            \"bankCode\": null,\n            \"firstName\": null,\n            \"lastName\": null,\n            \"accountIsBlackListed\": null,\n            \"accountToken\": null,\n            \"createdAt\": \"2019-01-28T11:35:32.61\",\n            \"updatedAt\": \"2019-01-28T13:03:16.752\"\n        }\n    }\n}",
      "language": "json",
      "name": "Re-query payment response"
    }
  ]
}
[/block]