Paypal Refund/Cancel Order auto refund - php

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

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

PayPal Express Checkout, update database on successful payment

Introduction
I´ve been looking at integrating a somewhat big project of mine with PayPal Express Checkout, and use that as the main system to handle payments on my site. Although their documentation is quite extensive, I really can´t find too good a place to start. Over the past few days, I´ve been presented with headache upon headache, in attempt to figure out how on Earth to integrate my site, as well as its database, with PayPal Express Checkout.
Summary
The JavaScript bit is pretty straight forward, and charging money using the client-side integration is extremely easy. But I also need a way to update fields in my database upon a payment going through (being successful), and from what I´ve understood so far, that can only be done by using the advanced server integration.
Problem
The problem, given the aforementioned reasons, is somehow managing to implement the advanced server integration solution, into my platform, in order to make way for changes in the database to occur upon a transaction being successful.
As mentioned before, the PayPal documentation is fairly extensive--problem is, I´ve never really went over using REST API´s, and it appears as though integrating what I´m after can only really be done using the PayPal REST API, to verify that the payment(s) have taken place.
Question
With all that being said, what I need help with is finding some place in all of this to start. I´m aware StackOverflow may not be the best place for a question like this, but it appears lots of people are having trouble with this exact question, and it´s an essential part of settings up any business on the web to get this to work.
Any pointers on where to start, or anything relating to the subject other than the PayPal documentation would be extremely helpful.
What follows is a minimal way to use Express Checkout with a server-side Payments REST API integration, including the associated code for client and server in JavaScript. I hope it helps.
You'll need to login to developer.paypal.com and create a REST API app. Your new app will be assigned a Client ID and Secret which you can use to request access tokens, which authorize your use of the PayPal REST API. The only app setting you need for what follows here is "Accept Payments". Sandbox accounts for testing are automatically created when you create an app.
Your (checkout) page loads PayPal's Express Checkout script, and a script you write renders a PayPal button:
// In your script:
paypal.Button.render({
env: 'sandbox', // Or 'production'.
commit: true, // Show 'Pay Now' button.
style: { // Style the button.
size: 'responsive',
color: 'silver',
shape: 'rect'
},
payment: function(data, actions) {
// See step 3.
},
onAuthorize: function(data, actions) {
// See step 7.
}
}, '#paypal-button');
Your customer clicks the rendered PayPal checkout button.
The payment function you define in the argument you give to paypal.Button.render() is called by PayPal's script, which sends a request to your server with your payload. Your payload contains (for example) cart contents and its associated data.
paypal.Button.render({
// ...
payment: function(data, actions) {
return paypal.request(
{
method: 'post',
url: '/your-api/create-payment',
json: {
order: items,
or: whatever
}
}
).then(
function(res) {
// Return the payment id received from your server.
return res.paymentId;
}
).catch(
function(err) {
// Oops, foobared.
}
);
},
// ...
}
Your server sends a request to api.sandbox.paypal.com, with your access token, to create a payment. When your server receives the newly created payment data from PayPal it (perhaps) persists the data on your server, but it must return the payment id to the client.
// HTTP request data for creating a payment.
{
method: 'post',
// Remove '.sandbox' below to use production endpoint.
url: 'https://api.sandbox.paypal.com/v1/payments/payment';
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + 'your access token here'
},
data: {
// Allows immediate payments with PayPal and credit cards in
// the Express Checkout dialog.
intent: 'sale',
// I suppose these were required by other PayPal REST services,
// but they won't be used because, for Express Checkout, you
// handle the confirmation/cancellation flow yourself, on the
// client.
redirect_urls: {
return_url: 'https://...'
cancel_url: 'https://...'
},
payer: {
payment_method: 'paypal',
},
note_to_payer: 'Thanks, you\'re magnificently awesome!',
transactions: [{
amount: {
total: total, // Your computed total.
currency: 'USD',
details: {
subtotal: subtotal, // Your computed subtotal.
tax: tax, // Your computed tax.
shipping: shipping // Your computed shipping.
// Other parameters are available for your use.
}
},
item_list: {
items: [
{
name: 'shinny shirt of mithril mail',
description: 'shinny',
sku: '12345',
quantity: 1,
price: 1.00,
currency: 'USD'
}
],
// Some properties aren't required, like this one.
shipping_method: 'USPS'
},
description: 'Your PayPal payment for a shinny shirt of mithril mail.',
// Not required and can be added later by patching the
// payment: maybe you don't want to add an invoice to and
// order until the payment is approved.
invoice_number: 12345
}]
}
}
The payment function you provided then receives the payment id from your server and uses it as its return value.
// See return value in step 3.
And now the Express Checkout payment dialog pops up for your customer, who must login in and confirm the payment, create an account, or checkout with a credit/debit card.
After the customer confirms payment by clicking the Pay Now button in the Express Checkout dialog, the onAuthorize function you define in the argument you give to paypal.Button.render() is called by PayPal's script. You can use this function's actions parameter to get() payment information from PayPal, which you can use in a confirmation page, etc. Use its data parameter to get the payment id and payer id, which must be sent in a request to your server to execute the payment.
onAuthorize: function(data, actions) {
return actions.payment.get().then(function(paymentDetails) {
// Get at the payment details like this...
// paymentDetails.payer.payer_info.first_name;
// paymentDetails.payer.payer_info.shipping_address.city;
// paymentDetails.payer.payer_info.shipping_address.state;
var payload = {
paymentId: data.paymentID,
payerId: data.payerID
};
return paypal.request(
{
method: 'post',
url: '/your-api/execute-payment',
json: payload {
paymentId: data.paymentID,
payerId: data.payerID
}
}
).then(
function(res) {
// Gotten paid! Show confirmation page.
}
).catch(
function(err) {
// Dang it.
}
);
});
}
Your server receives the payment id and payer id from the client and makes another request to PayPal, this time to execute the payment. The transaction is complete if the execute request returns successfully. And now you can persist (or update) the payment data on your server.
// HTTP request data for executing a payment.
{
method: 'post',
// Remove '.sandbox' below to use production endpoint.
url: 'https://api.sandbox.paypal.com/v1/payments/payment/' + paymentId + '/execute/',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + 'your access token here'
},
data: {
payer_id: payerId
}
}
The client's latest request to your server completes successfully and you show a confirmation page, optionally with payment info from step 7 or from your server.
As for a place to start, here's what I suggest:
Automate requesting and storing your access token on your server. You'll need to store it because PayPal rate-limits token requests. So, either automate keeping it fresh or request a new one whenever you need to. I believe they expire in eight or nine hours; in any case, the expires-in time is given to you with the token. https://developer.paypal.com/docs/api/overview/
Build the /your-api/create-payment server endpoint. Test it with requests from an API tool like Postman using your access token. When everything goes well your server will make a successfull call to PayPal to create a payment, and you can explore the data in the response. It doesn't matter that you don't plan to execute the payment...it's the sandbox after all. Then build in your server-side persistence (if you want) and return the payment id to the client.
Next, load the PayPal script and your checkout-button rendering script on your site, and see if the Express Checkout login appears when you click the checkout button. If an error occurs in the create-payment process you'll see an error rather than the Express Checkout login.
When your system is creating payments and you can log in at the Express Checkout dialog with your sandbox credentials, build the /your-api/execute-payment endpoint. When your server has a working execute-payment endpoint you should be able to log in with Express Checkout and use your sandbox buyer account to complete a payment.
If after all that you think you'll have a go, the docs you want to pay attention to are https://developer.paypal.com/docs/api/ > API Reference > Payments API > Payments. There are five sections: create, execute, show, update and list. Read them. It will help.

How to retrieve information about a transaction just performed?

This is my code:
$gateway = GatewayFactory::create('PayPal_Express');
$gateway->setUsername('name');
$gateway->setPassword('pass');
$gateway->setSignature('sig');
$gateway->setTestMode(true);
$resp = $gateway->purchase(
array(
'cancelUrl' => 'mysite/',
'returnUrl' => 'mysite/success',
'description' => "mysite item",
'amount' => $amount, //final amount
'currency' => 'EUR'
)
)->send();
if ($resp->isSuccessful()) {
// payment was successful: update database
// never reached
$a = new database('database');
$a->write database;
$dbp = null; die;
print_r($resp);
} elseif ($resp->isRedirect()) {
// redirect to offsite payment gateway
$resp->redirect();
} else {
echo $resp->getMessage();
header('Location: mysite/error');
exit;
}
How can I retrive informations about the transaction after the redirect?
How to adapt this code for credit card on paypal?
From your comments, I would assume that you're not getting to the successful payment stage.
With this in mind, let's take a look at the express checkout flow and compare it to a DoDirectPayment api call
===============
SetExpressCheckout API Call - the Shopping Cart announces the checkout details and gets back an "Express Checkout Token". The token identifies the checkout session that the shop has requested from PayPal
The buyer is redirected to the Express Checkout URL and the token gets appended to the redirect URL - https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-6C677292NP7377708
(if you skip step 5, you have to add a useraction=commit parameter to the redirect URL)
The buyer logs in and approves the payment
The buyer is redirected back to the Return URL announced in the SetExpressCheckout API call with the PayerID and the Token added to the return URL as HTTP GET Parameters
5. The integration initiates a GetExpressCheckoutDetails API call, retrieves the shipping info and displays one last overview and the added shipping charges to the buyer
Once the buyer decides to complete the payment, he initiates the payment through your integration on your website. The website then calls the DoExpressCheckoutPayment API
===============
For Credit Card Payments via the DoDirectPayment API, the API NVP Request and Response would look like this - it should be pretty straight forward.
Request:
VERSION = 109.0
METHOD = DoDirectPayment
PAYMENTACTION = Sale
IPADDRESS = 192.168.0.1
AMT = 0.01
CREDITCARDTYPE = Visa
ACCT = xxxxxxxx6840
EXPDATE = 102020
CVV2 = 123
FIRSTNAME = John
LASTNAME = Test
STREET = 12312 Port Grace Blvd
CITY = La Vista
STATE = NE
COUNTRYCODE = US
ZIP = 68128
CURRENCYCODE = USD
Response:
TIMESTAMP=2015-01-20T16:00:27Z
CORRELATIONID=180513f33ad52
ACK=Success
VERSION=109.0
BUILD=14726230
AMT=0.01
CURRENCYCODE=USD
AVSCODE=X
CVV2MATCH=M
TRANSACTIONID=0PA61839GE498951M}
===============
Judging by your comments in the code, you're assuming that the transaction completes once step 4 is complete.
As I do not see any code to initiate a DoExpressCheckoutPayment API call, you will need to make sure at least step 6 is being done.
https://devtools-paypal.com/integrationwizard/ has standalone sample code that might help.
However, using an SDK based integration will relieve much of the pain:
https://devtools-paypal.com/guide/expresscheckout/php?interactive=ON&env=sandbox
...
If you want to retrieve Payment Details at a later stage, you can run a GetTransactionDetails API call against the Transaction ID returned in the DoDirectPayment API call or the DoExpressCheckoutPayment calls.
See: https://developer.paypal.com/webapps/developer/docs/classic/api/merchant/GetTransactionDetails_API_Operation_NVP/
You can use Instant Payment Notification to receive notifications about the just completed transaction. IPN is the recommended way to go.

EBS payment gateway integration using 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

pay pal returnurl to return users pay pal account email address

I'm using PHP.
Is it possible when paypal returns to my site after taken the payment that it could also pass me the email address (paypal username) so that I may use this to send them an email?
I'm trying to keep my site as simple as possible and I don't want to ask the customer for a load of information up front.
My ideal flow would be:
Take Payment > Add record to database > email customer with username and password
The customer can then log in and fill the rest in at their own leisure.
Is it possible to get this variable?
Thanks in advance.
Yes...see the receiver_email variable that was passed back.
Guide here: https://cms.paypal.com/cms_content/GB/en_GB/files/developer/IPNGuide.pdf
See Pages 42-43
This page shows the things you can get back from PayPal after they process a payment.
IPN and PDT Variables
Here is on example I made in Codeigniter.
/* Receives a form data from paypal that is processed after payment goes through.
* It will update the database entry with a transaction id.
*/
function epayment_notify(){
$this->load->model('pament_notice_model');
echo "Hi<br>";
$postvars = isset($_POST)? $_POST : array("no post");
/* echo "</pre>Post Vars:<br><pre>";
print_r($postvars);
echo "</pre>Refurl:<br><pre>";
Check for the transaction ID and put it in the pament_notice table if possible.
*/
if (isset($postvars['item_number']) && $postvars['item_number'] > 0 && isset($postvars['txn_id'])){
/* make sure that payment_number is empty on this row. */
log_message('info',"PayPal transaction received.");
if ($this->pament_notice_model->make_sure_payment_number_is_empty($postvars['item_number'])){
//writes the message to the local log file in CI
log_message('debug',"PayPal payment number is empty.");
/* set the txn_id in the slot */
$data = array('payment_number' => $postvars['txn_id']);
$this->db->where('entry_id',$postvars['item_number']);
$this->db->update('pament_notice',$data);
log_message('debug',"payment number updated. item:".$postvars['item_number']);
log_message('debug',"payment actual cost. payment_gross:".$postvars['payment_gross']);
} else {
log_message('error',"PayPal transaction attempted on non-empty payment number.");
if (isset($postvars['item_number']))
log_message('error',"failed request item_number :".$postvars['item_number']);
if (isset($postvars['txn_id']))
log_message('error',"failed request txn_id:". $postvars['txn_id']);
}
} else {
log_message('info',"PayPal payment transaction sent with invalid data.");
if (!isset($postvars['item_number']))
log_message('error',"item_number is not set");
if (isset($postvars['item_number']))
log_message('error',"failed request item_number :".$postvars['item_number']);
if (!isset($postvars['txn_id']))
log_message('error',"txn_id is not set\n");
if (isset($postvars['txn_id']))
log_message('error',"failed request txn_id:". $postvars['txn_id']);
}
}
There are a couple of way of handling this.
The easiest method is to collect that data prior to sending the user to paypal.
Store it in the users current session, and have paypal redirect the user back to your page automatically.
The second is to set up the Payment Data Transfer option. I haven't fully implemented this but there is Documentation on paypal's developer site. It basically sends a token back to your site when the user makes payment and you have to perform another HTTP post to retrieve the user data.

Categories