sudiptpa / esewa

Integrate eSewa payment gateway for online payments. A php library to comsume eSewa payment gateway API, built on top of Omnipay Payment processing library. Read the blog post to follow the step by step guide on how to integrate esewa with Laravel PHP framework.
https://sujipthapa.co/blog/esewa-online-payment-gateway-integration-with-php
MIT License
6 stars 2 forks source link

Issue with Epay::Payment Verification - https://developer.esewa.com.np/#/epay?id=payment-verification #17

Closed sudiptpa closed 4 years ago

sudiptpa commented 4 years ago

I just noticed a bug in this package on verify transaction after successful payment is made.

How to recreate?

The docs says, to verify the transaction we need to send GET request like below.

<body>
    <form action="https://uat.esewa.com.np/epay/transrec" method="GET">
    <input value="100" name="amt" type="hidden">
    <input value="epay_payment" name="scd" type="hidden">
    <input value="ee2c3ca1-696b-4cc5-a6be-2c40d929d453" name="pid" type="hidden">
    <input value="000AE01" name="rid" type="hidden">
    <input value="Submit" type="submit">
    </form>
</body>

The Javascript, PHP, PYTHON code snippet over the docs says POST request.

This package implements the PHP version of the API.

I tried with CURL like below.

$url = "https://uat.esewa.com.np/epay/transrec";

$data =[
    'amt' => 24.0,
    'rid' => '00008FU',
    'pid' => 'TEST2019',
    'scd' => 'epay_payment',
];

$curl = curl_init($url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($curl);

curl_close($curl);

var_dump($response);

// output

<response>
<response_code>
Success
</response_code>
</response>

But, this package consumes the Guzzle HTTP library for HTTP request.

$url = 'https://uat.esewa.com.np/epay/transrec';

$data = [
    'amt' => 24.0,
    'rid' => '00008FU',
    'pid' => 'TEST2019',
    'scd' => 'epay_payment',
];

$response = $this->httpClient->request('POST', $url, [
     'Accept' => 'application/json',
     'Content-Type' => 'application/json',
 ], json_encode($data));

$output = $response->getBody()->getContents();

var_dump($output);

// output
// "<html><head><title>Request Rejected</title></head><body>The requested URL was rejected. Please consult with your administrator.<br><br>Your support ID is: <15212239662342379704><br><br><a href='javascript:history.back();'>[Go Back]</body></html>"

If anyone has gone through this error before, feel free to submit a PR with a fix.

Note: Issue description was updated later while testing and debugging.

khadka7 commented 4 years ago

Does Esewa Payment Verification accept $data = [ 'oid' => 'ABAC2098', 'amt' => 27.0, 'refId'=> 0000822, ];

sudiptpa commented 4 years ago

@khadka7 refId is the reference number esewa return on payment success response, in the varification we need to send the exact value to verify the transaction.

If you want to simulate the real running esewa integration and test feel free to clone this repo - https://github.com/sudiptpa/laravel5.8-example which has real esewa integration to test.

khadka7 commented 4 years ago

I tried with guzzle http , when i tried with debug true it says "curl_setopt_array(): cannot represent a stream of type Output as a STDIO FILE*"

sudiptpa commented 4 years ago

Did you miss form_params?

$response = $client->request('POST', $url, [
    'debug' => true,
    'form_params' => $data,
]);
khadka7 commented 4 years ago

nope, i did same as above code, $response = $client->request('POST', $url, [ 'debug' => true, 'form_params' => $data, ]);

sudiptpa commented 4 years ago

Got this response via console mode via Curl.

$ curl -X POST -# -H "Content-Type:application/x-www-form-urlencoded" -d "amt=24.0&rid=00008FU&pid=TEST2019&scd=epay_payment" https://uat.esewa.com.np/epay/transrec -vvv
Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 103.255.126.45:443...
* TCP_NODELAY set
* Connected to uat.esewa.com.np (103.255.126.45) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: CN=*.esewa.com.np
*  start date: Mar 25 00:00:00 2020 GMT
*  expire date: Apr  6 23:59:59 2021 GMT
*  subjectAltName: host "uat.esewa.com.np" matched cert's "*.esewa.com.np"
*  issuer: C=GB; ST=Greater Manchester; L=Salford; O=Sectigo Limited; CN=Sectigo RSA Domain Validation Secure Server CA
*  SSL certificate verify ok.
> POST /epay/transrec HTTP/1.1
> Host: uat.esewa.com.np
> User-Agent: curl/7.68.0
> Accept: */*
> Content-Type:application/x-www-form-urlencoded
> Content-Length: 50
> 
* upload completely sent off: 50 out of 50 bytes
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Content-Type: text/html
< Date: Tue, 14 Jul 2020 06:18:59 GMT
< P3P: CP="{}"
< Set-Cookie: TSc4fa6d1f029=08ea48504aab28005378ab4ff4f812239bd89fd22eb929eefbadb63ea34d7596695b5fb635bf0dd1ec76a67d0c52a157; Max-Age=30;Path=/;Secure
< Vary: Accept-Encoding
< Transfer-Encoding: chunked
< 
<response>
<response_code>
Success
</response_code>
</response>
* Connection #0 to host uat.esewa.com.np left intact
sudiptpa commented 4 years ago

Request headers with Guzzle vs curl.

Guzzle

Screenshot from 2020-07-13 23-36-40

CURL

Screenshot from 2020-07-13 23-36-57

Still no luck fixing it to work with Guzzle.

sudiptpa commented 4 years ago

@khadka7

$response = $client->request('POST', $url, [ 'debug' => true, 'form_params' => $data, ]);

The way you did this code above is only correct in the Guzzle implementation, but this package relies on Omnipay. See below for the correct way of Omnipay.

// XML
 $response = $this->httpClient->request('POST', $this->endpoint, [], http_build_query($data));
 $result = simplexml_load_string($httpResponse->getBody()->getContents());
// JSON 
 $response = $this->httpClient->request('POST', $this->endpoint, [
     'Accept' => 'application/json',
     'Content-Type' => 'application/json',
 ], json_encode($data));

 $result = json_decode($response->getBody()->getContents(), true);

I tried both of this, the error is not appearning, but the eSewa server returns the below message all the time.

Request RejectedThe requested URL was rejected. Please consult with your administrator.

Your support ID is: < 7625424639724587258>

[Go Back]
chistel commented 4 years ago

just pass user-agent header to the guzzle option like this

$response = $this->httpClient->request('POST', $this->endpoint, [ 'headers' => [ 'User-Agent' => $_SERVER['HTTP_USER_AGENT'], ] ]);

and the issue would be sorted

sudiptpa commented 4 years ago

@chistel No Luck !

sagarlava commented 4 years ago

Accept: / can pass this request header in Guzzle?

chistel commented 4 years ago

I had same issue yesterday, passing the user agent as an header solved it.

sudiptpa commented 4 years ago

@sagarlava @chistel - I tried with that header already.

I am not exactly sure what I'm missing, and it does not want to work really on my end at all. I even have Laravel v7.0 setup locally and a basic integration workflow to test it.

This issue is becoming more interesting to dig in to find out why the Guzzle version of code does not work. Or their server throwing that error?

chistel commented 4 years ago

it's partly from their server. Share a snippet of your you attempted

sudiptpa commented 4 years ago

https://github.com/sudiptpa/esewa/pull/18 Ok Fixed, Thanks !