EBS payment gateway integration using PHP - php

i need to integrate ebs payment gateway. i am searching lot but i could find the solution.
Response is provided using POST method to the URL defined under ReturnURL parameter in the payment request. $response['ResponseCode'] == 0 means transaction successfully completed. Other than 0 value transactions failed. I can't find $response['ResponseCode'] == 0.
here my code
if(isset($_GET['DR'])) {
require('Rc43.php');
$DR = preg_replace("/\s/","+",$_GET['DR']);
$rc4 = new Crypt_RC4($secret_key);
$QueryString = base64_decode($DR);
$rc4->decrypt($QueryString);
$QueryString = split('&',$QueryString);
$response = array();
foreach($QueryString as $param){
$param = split('=',$param);
$response[$param[0]] = urldecode($param[1]);
}
}

I would understand how exactly the integration to EBC is done and look at one of the existing Broadleaf Payment modules as a template.
For example:
- Does EBC provide an API for direct server to server communication? (i.e. the Credit Card information is passed to your server and then relayed to the gateway? If so, take a look at http://docs.broadleafcommerce.org/curre ... odule.html
- Does EBC provide a mechanism for a Transparent Redirect or Silent Post? (i.e. the Credit Card form is sent directly to EBC thereby bypassing the merchant servers? If so, take a look at http://docs.broadleafcommerce.org/curre ... e.net.html
- Does EBC provide a mechanism for a Hosted Order Page? (i.e. you get redirected to EBC's servers to enter your credit card information. If so, take a look at http://docs.broadleafcommerce.org/curre ... odule.html)
The many different integration options that the Payment Gateway provides will determine how Broadleaf should integrate with it.
Hope that helps.
Reference : http://www.fetchflow.com/blog/authorize-net-invoicing

Related

How do you capture a payment in a webhook in Stripe's pre-built checkout flow?

I currently have an Opayo (SagePay) Server integration where I'm apparently spoilt by an ability to simply respond to a payment notification callback with an ERROR status to reject/void a transaction if there is a problem fulfilling an order on my side. I think, there is some sort of automatic authorise then capture happening behind the scenes, where a payment is only captured if a success/OK status is returned by my notification handler.
I'm looking at how I can achieve the same with a Stripe checkout integration (Pre-built Checkout, PHP with webhooks) and it seems that I need to to use authorisation and manual capturing:
$session = \Stripe\Checkout\Session::create([
...
'payment_intent_data' => [
'capture_method' => 'manual',
],
]);
In the sample code and documentation (which is generally excellent, but I feel falls short here), it shows how to create a webhook to handle the completion of the checkout session:
// Handle the checkout.session.completed event
if ($event->type == 'checkout.session.completed') {
$session = $event->data->object;
// Fulfill the purchase...
fulfill_order($session);
}
Curiously, the payment_status of the transaction is not checked and the example suggests you would simply fulfil your order here. I can only assume, if you are not using a delayed payment method then you can assume the payment is successful at this point, although it seems a dangerous assumption to make.
Further along in the documentation, under "Handle delayed notification payment methods Server-side", we have a fuller example, where the payment status is actually checked before fulfilling the order:
switch ($event->type) {
case 'checkout.session.completed':
$session = $event->data->object;
// Save an order in your database, marked as 'awaiting payment'
create_order($session);
// Check if the order is paid (e.g., from a card payment)
//
// A delayed notification payment will have an `unpaid` status, as
// you're still waiting for funds to be transferred from the customer's
// account.
if ($session->payment_status == 'paid') {
// Fulfill the purchase
fulfill_order($session);
}
...
If I am using the manual capture method, how exactly should the code above be used/adapted? Presumably the payment_status will not be paid so what do I check for and how do I access the PaymentIntent to be able to capture it? Should this all happen in the checkout.session.completed event?
A code example would be great; unfortunately there is only this footnote in the documentation:
To capture an uncaptured payment, you can use either the Dashboard or the capture endpoint. Programmatically capturing payments requires access to the PaymentIntent created during the Checkout Session, which you can get from the Session object.
I have checked the online code samples but this exact scenario isn't covered.
EDIT: Adding below my understanding of the flow I need with questions:
switch ($event->type) {
case 'checkout.session.completed':
$session = $event->data->object;
if ($session->payment_status == 'unpaid') {
// We need to capture the payment if we have arrived here?
// Is this the only scenario where we would end up here?
// How do we get the PaymentIntent, what status if any should we check on it?
// Attempt to fulfil the purchase here, if all good then
// capture the payment
} else if ($session->payment_status == 'paid') {
// Assume this was not an auth/capture type payment?
// There is no other scenario where we would end up here?
}
...
If you receive the checkout.session.completed event, then the synchronous payment method completed successfully.
For async payment methods, there are other events:
checkout.session.async_payment_succeeded
checkout.session.async_payment_failed
I'm not sure why you'd use auth and capture here, since the payment is successful either upon receipt of checkout.session.completed or checkout.session.async_payment_succeeded, but if you need to, you'd set the option to do so here and then you'd need to capture the Payment Intent associated with the Checkout Session.
If you need to determine if the Charge was captured or not, you'd need to retrieve the Payment Intent and look a the Charge's captured value: https://stripe.com/docs/api/charges/object#charge_object-captured

How to use PayPal Express Payments (PHP)

I am using the PayPal PHP SDK found here: https://github.com/paypal/Checkout-PHP-SDK
And I am somewhat puzzled in terms of how to complete the process.
On the outset this seems quite simple:
Setup your credentials
Create the Order
Check the result, and re-direct to approval link
User makes a payment and is sent to the SUCCESS link that you would have set.
i.e. http://example.com/pay/complete/paypal?token=8UK32254ES097084V&PayerID=SEQNPLB2JR9LY
And this is where things get a bit shakey.
Conveniently, a token and a PayerID is returned.
And according to the documentation, you now need to "Capturing the Order" and the following code is provided:
use PayPalCheckoutSdk\Orders\OrdersCaptureRequest;
// Here, OrdersCaptureRequest() creates a POST request to /v2/checkout/orders
// $response->result->id gives the orderId of the order created above
$request = new OrdersCaptureRequest("APPROVED-ORDER-ID");
$request->prefer('return=representation');
try {
// Call API with your client and get a response for your call
$response = $client->execute($request);
// If call returns body in response, you can get the deserialized version from the result attribute of the response
print_r($response);
}catch (HttpException $ex) {
echo $ex->statusCode;
print_r($ex->getMessage());
}
What is confusing is that the OrdersCaptureRequest requires an "APPROVED-ORDER-ID"
But all that has been returned is a "token" and a "PayerID".
So my question is, what is this APPROVED-ORDER-ID, and where do I get it?
Thank you!
what is this APPROVED-ORDER-ID, and where do I get it
At that moment, sourced from token= . It should correspond to an Order Id you received in the response to your step 2 ("Create the Order")
For step 3, it is better to use no redirects whatsoever. Instead, implement this front-end UI, which offers a far superior in-context experience that keeps your site loaded in the background: https://developer.paypal.com/demo/checkout/#/pattern/server
There is no reason for a modern website to be redirecting unnecessarily

PHP verify Paypal webhook signature

I'm having trouble trying to verify paypal webhook signatures with PHP. Using the new V2 of paypals APIs I am receiving the paypal webhook on my page.
However I can not seem to successfully validate the signature.
From the link HERE I got some sample webhook validation PHP code from paypal.
I can not get it working, I don't know where I am supposed to get bootstrap.php from in the paypal code. The paypal information seems incomplete or half baked. Paypal seems to be terrible to set-up compared to Stripe.
Has anyone got experience of validating paypal webhook signatures with PHP when using V2 of the paypal APIs ?
Well I have come to the conclusion that the Paypal developer information is rather poor, it is scatted all over the place, on multiple different pages and sites. The examples they give on the paypal developer website HERE are not a complete picture of what is required to validate a webhook signature. Stripe developer documentation is much better formatted and concise.
Installing Paypal Checkout V2 SDK does not give you the necessary development tools to validate paypal webhook signatures i.e. you can process payments and receive webhooks but you can not validate the webhook signatures....I know stupid. Tip do not download the SDK directly as you will not include the required autoload.php file. Use composer to install Paypal Checkout V2 SDK so that you get the autoload.php file.
Once you are to a point that you can process payments and receive webhooks form paypal you need to install the another SKD called Paypal Rest API SDK. Again use composer to install the SDK so that you get a autoload.php file which you will need.
When you install Paypal Rest API SDK amazingly you will still be missing files that are required to validate the payapl webhook signatures. I can find no mention of these anywhere on the paypal developer website.
bootstrap.php & common.php
Thanks to #Grumpy I got some samples provided on github HERE
Note you will probably need to modify the samples a bit in order to get them working with your website. Tip set the logger to false and save yourself some bother if you don't have the necessary access permissions to write.
Once you have bootstrap.php & common.php files created you can write the code for your webhook endpoint page i.e. the page that paypal sends the webhook to. I have included my PHP code below for how to validate and then process the paypal webhook. Tip in the below code you need to specify the webhook ID, each webhook that you create in paypal has a unique ID. Also when you are testing you can not use webhook simulator as this will fail validation, you can make manually a payment with your sandbox account details which will trigger a webhook payment event.
Paypal sure don't make it easy, their documentation is all over the place compared to Stripe. The Paypal webhooks can sometimes take several minutes to arrive after a payment is made, very frustrating when trying to debug. Also it's a bit ridiculous that they have a webhook simulator on the paypal developer website that can not be used to validate signatures...if stripe can do it why can't paypal.
<?php
//get the webhook payload
$requestBody = file_get_contents('php://input');
//check if webhook payload has data
if($requestBody) {
//request body is set
} else {
//request body is not set
exit();
}
use \PayPal\Api\VerifyWebhookSignature;
use \PayPal\Api\WebhookEvent;
$apiContext = require __DIR__ . '/bootstrap.php';
//Receive HTTP headers that you received from PayPal webhook.
$headers = getallheaders();
//need header keys to be UPPERCASE
$headers = array_change_key_case($headers, CASE_UPPER);
/*
example header paypal signature content for webhook, these values are recieved as an array, we then need to use this data to verify the payload
CONTENT-LENGTH : 1376
CORRELATION-ID : 6db85170269e7
USER-AGENT : PayPal/AUHD-214.0-54377828
CONTENT-TYPE: application/json
PAYPAL-AUTH-ALGO : SHA256withRSA
PAYPAL-CERT-URL : https://api.paypal.com/v1/notifications/certs/CERT-360caa42-fca2a784-5edc0ebc
PAYPAL-AUTH-VERSION : v2
PAYPAL-TRANSMISSION-SIG : Hc2lsDedYdSjOM4/t3T/ioAVQqFPNVB/AY/EyPNlavXk5WYUfnAmt9dyEP6neAPOjFHiVkXMK+JlLODbr6dalw6i26aFQdsPXqGl38Mafuu9elPE74qgsqNferUFgHi9QFXL+UZCNYcb4mvlDePXZIIAPbB0gOuFGOdEv2uqNwTCSAa/D8aguv1/51FWb3RkytFuVwXK/XNfIEy2oJCpDs8dgtYAZeojH8qO6IAwchdSpttMods5YfNBzT7oCoxO80hncVorBtjj1zQrkoynEB9WNNN9ytepNCkT8l29fQ4Sx/WRndm/PESCqxqmRoYJoiSosxYU3bZP7QTtILDykQ==
PAYPAL-TRANSMISSION-TIME : 2020-04-05T14:40:43Z
PAYPAL-TRANSMISSION-ID : 6dec99b0-774b-11ea-b306-c3ed128f0c4b
*/
//if any of the relevant paypal signature headers are not set exit()
if(
(!array_key_exists('PAYPAL-AUTH-ALGO', $headers)) ||
(!array_key_exists('PAYPAL-TRANSMISSION-ID', $headers)) ||
(!array_key_exists('PAYPAL-CERT-URL', $headers)) ||
(!array_key_exists('PAYPAL-TRANSMISSION-SIG', $headers)) ||
(!array_key_exists('PAYPAL-TRANSMISSION-TIME', $headers))
)
{
exit();
}
//specify the ID for the webhook that you have set up on the paypal developer website, each web hook that you create has a unique ID
$webhookID = "ENTER_YOUR_WEBHOOK_ID_HERE";
//start paypal webhook signature validation
$signatureVerification = new VerifyWebhookSignature();
$signatureVerification->setAuthAlgo($headers['PAYPAL-AUTH-ALGO']);
$signatureVerification->setTransmissionId($headers['PAYPAL-TRANSMISSION-ID']);
$signatureVerification->setCertUrl($headers['PAYPAL-CERT-URL']);
$signatureVerification->setWebhookId($webhookID);
$signatureVerification->setTransmissionSig($headers['PAYPAL-TRANSMISSION-SIG']);
$signatureVerification->setTransmissionTime($headers['PAYPAL-TRANSMISSION-TIME']);
$signatureVerification->setRequestBody($requestBody);
$request = clone $signatureVerification;
try {
$output = $signatureVerification->post($apiContext);
} catch (Exception $ex) {
//error during signature validation, capture error and exit
ResultPrinter::printError("Validate Received Webhook Event", "WebhookEvent", null, $request->toJSON(), $ex);
exit(1);
}
$sigVerificationResult = $output->getVerificationStatus();
// $sigVerificationResult is a string and will either be "SUCCESS" or "FAILURE"
//if not webhook signature failed validation exit
if($sigVerificationResult != "SUCCESS"){
exit();
}
else if($sigVerificationResult == "SUCCESS"){
//paypay webhook signature is valid
//proceed to process webhook payload
//decode raw request body
$requestBodyDecode = json_decode($requestBody);
//pull whatever info required from decoded request body, some examples below
$paymentSystemID = $requestBodyDecode->id;
$eventType = $requestBodyDecode->event_type;
//do something with info captured from the webhook payload
}
This seems to work with php 8.1:
if (openssl_verify(
data: implode(separator: '|', array: [
$httpPayPalTransmissionId,
$httpPayPalTransmissionTime,
$webhookID,
crc32(string: $rawRequestBody),
]),
signature: base64_decode(string: $httpPayPalTransmissionSignature),
public_key: openssl_pkey_get_public(public_key: file_get_contents(filename: $cachedHttpPayPalCertUrl)),
algorithm: 'sha256WithRSAEncryption'
) === 1) {
die('OK');
} else {
die('FAILED');
}

Paypal Refund/Cancel Order auto refund

I've been searching about this and everyone seems to say that to refund, you must go to paypal website, etc. then the customer will issue a refund there.
What I need is this:
When the customer wants to refund, an approval will be sent to admin in my website, then when the admin approves, the admin will, inside the website, select the amount of money to payback the customer. (Then I guess, it will direct to paypal and type the email and password?)
Is this possible? That every process is in my website except for the paying? I didn't seem to find solutions, I don't have any lead also. Thanks.
Absolutely Possible,
First of all do make a refund request you must store Paypal's Transaction ID
Once Your admin clicks refund approval button
var refundTransactionRequestType = new RefundTransactionRequestType
{
Version = RefundTransactionRequestVersion, //it must be same version with Express Checkout Request Version
RefundTypeSpecified = true,
TransactionID = transactionId //HERE You need to set Paypal's TransactionID
};
var refundTransactionRequest = new RefundTransactionRequest(
_customSecurityHeaderType, //CustomSecurityHeaderType will have your paypal merchant credentials
new RefundTransactionReq //Your RefundTransactionRequestType
{
RefundTransactionRequest = refundTransactionRequestType
});
RefundTransactionResponse refundTransactionResponse;
try
{
PayPalAPIInterface apiInterface = new PayPalAPIInterfaceClient();
refundTransactionResponse = apiInterface.RefundTransaction(refundTransactionRequest);
}
catch (FaultException err)
{
return 123123;//Error CODE
}
The Code is for C# but it will have the same logic
Here is reference for RefundTransaction SOAP
Here is reference for RefundTransaction NVP

Using PayPal Integration Wizard: Problems with empty variables

What I have to do:
Client defines a quite tricky product.
Price is calculated according to different Parameters via javascript.
Client states, that he wants to pay with PayPal and sends form.
When checking the content of the form, I want to react on his wish to pay via PayPal.
I used the integration wizard. I implemented paypals expresscheckout.php and paypalfunctions.php.
I set the variables at the start of paypalfunctions.php (sandbox). Made the rest of the code as given and tracked it until the paypal-call.
There is a call to PayPal in their own function "hash_call", where they use these variables.
But they are empty.
code in paypalfunctions.php
Defines all the global variables and the wrapper functions
********************************************/
$PROXY_HOST = '127.0.0.1';
$PROXY_PORT = '808';
$SandboxFlag = true;
//'------------------------------------
//' PayPal API Credentials
//' Replace <API_USERNAME> with your API Username
//' Replace <API_PASSWORD> with your API Password
//' Replace <API_SIGNATURE> with your Signature
//'------------------------------------
$API_UserName="myemail";
$API_Password="mypw";
$API_Signature="mysignature";
...
code in hash_call: The function hash_call ist part of paypalfunctions.php
function hash_call($methodName,$nvpStr)
{
...
//declaring of global variables
global $API_Endpoint, $version, $API_UserName, $API_Password, $API_Signature;
...
Whats going wrong?
There is a link zu the wizard: https://devtools-paypal.com/integrationwizard/ecpaypal/code.php
Piet
It is possible that you are using the wrong API Credentials.
I noticed in your example you put the following:
$API_UserName="myemail";
$API_Password="mypw";
$API_Signature="mysignature";
Just to be clear your API User name is not your Email address. Your API Password is not your PayPal Password.
Just in case you need it, here is an example of what API credentials look like and how to request them from your PayPal Account. You can use these same instructions on your Sandbox account as well:
API Credential Information
Also make certain of your endpoint. The endpoint is where you are pointing your customers. Are you pointing them at the live site or the sandbox site?
Just in case you need them, here is the API endpoint information:
PayPal API Endpoint Information
Make certain that if you are using Sandbox Credentials you are using Sandbox endpoints, and if you are using live credentials, make certain to use the live endpoint.

Categories