Use PayPal PHP Merchant SDK to settlements and refund all or part of a payment.

The PayPal refund API operation issues a refund to the PayPal account holder associated with a transaction. PayPal refund API operation can be used to issue a full or partial refund for any transaction.

For settlements and refund money, we have required one product’s transaction id to getting this please refer our previous blog PayPal Integration in PHP Using PDO

In this blog post, we are going to demonstrate how merchant issue refunds to their product’s buyer.

 


Paypal refund or settlements process using Paypal refund api in php

 


Project Integration

For configuration PayPal PHP merchant SDK, add your account credentials in the configuration.php. You can find this file in downloaded project “root folder”.

 // Demo Signature Credential
"acct1.UserName" => "demo-facilitator_api1.outlook.com",
"acct1.Password" => "PDwertWU6FDBNKY",
"acct1.Signature" => "ANGx9fhOeeeeeecx8nbBWeDOIbzW1",

Then you will be ready to run the project. You can also refer the install.txt file given in download code folder.

 


Tutorial Scripts in detail

Below are the details of the code used in this tutorial with proper explanation.

Index.php

In index.php merchant can put transaction id on given input box then click on Get Details button. After that, all transaction details will appear related to transaction id. Now merchants can refund full or partial amount to concerned person.

<?php
require_once('../PPBootStrap.php');
$transactionID_err = "";
if (isset($_POST['transID'])) {
/*
* The GetTransactionDetails API operation obtains information about a specific transaction.
*/
$transactionDetails = new GetTransactionDetailsRequestType();
/*
* Unique identifier of a transaction.
*/
$transactionDetails->TransactionID = $_POST['transID'];

$request = new GetTransactionDetailsReq();
$request->GetTransactionDetailsRequest = $transactionDetails;

/*
* ## Creating service wrapper object
Creating service wrapper object to make API call and loading
Configuration::getAcctAndConfig() returns array that contains credential and config parameters
*/
$paypalService = new PayPalAPIInterfaceServiceService(Configuration::getAcctAndConfig());
try {
/* wrap API method calls on the service object with a try catch */
$transDetailsResponse = $paypalService->GetTransactionDetails($request);
} catch (Exception $ex) {
include_once("../Error.php");
exit;
}
if ($transDetailsResponse->Ack == 'Failure') {
$transactionID_err = 'TransactionID is not valid.';
}
}
?>
<html>
<head>
<title>Paypal Settlements and Refunds in PHP</title>
<link rel="stylesheet" type="text/css" href="css/style.css">
<link rel="stylesheet" type="text/css" href="css/popup-style.css" />
<link rel="stylesheet" type="text/css" href="css/global.css">
<link rel="stylesheet" type="text/css" href="css/loadding.css">
<meta name="robots" content="noindex, nofollow">
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-43981329-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script');
ga.type = 'text/javascript';
ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s);
})();
</script>
</head>
<body>
<div id = "main">
<h1>Paypal Settlements and Refunds in PHP</h1>
<div id = "container">
<h2>Refund to the PayPal Account Holder Associated With a Transaction.</h2>
<hr/>
<div class="fg-row">
<form action="index.php" method="POST" id="myform" >
<div class="col-md-10 nopadding">
<label class="block fg-label">TransactionID * (Get Transaction ID via : <a target="blank" href="https://www.formget.com/tutorial/paypal_simple_integration/payments.php">PayPal Integration in PHP Using PDO.</a>)</label>
<input class="fg-fw text fg-input" placeholder="" type="text" onclick="" name="transID">
<p class="fg-help red"><?php echo $transactionID_err; ?></p>
</div>
<div class="col-md-2 nopadding">
<div style="margin-left: 5%; margin-top: 14%;">
<input type="submit" value="Get Detail" id="submit" name="submit">
</div>
</div>
</form>
<div class="fg-clear"></div>
</div>
<?php
if (isset($transDetailsResponse)) {
if ($transDetailsResponse->Ack == 'Success') {
$currency_value = $transDetailsResponse->PaymentTransactionDetails->PaymentInfo->GrossAmount->currencyID;
?>
<div class="fg-row">
<div class="col-md-12 nopadding">
<table id="results" >
<thead>
<tr class="head">
<th colspan="2">Payer Information</th>
</tr>
</thead>
<tbody>
<tr class="row-data unread_new">
<td>Payer Name</td>
<td><?php
echo $transDetailsResponse->PaymentTransactionDetails->PayerInfo->PayerName->FirstName;
echo ' ';
echo $transDetailsResponse->PaymentTransactionDetails->PayerInfo->PayerName->LastName;
?></td>
</tr>
<tr class="row-data unread_new">
<td>Payer Email-ID</td>
<td><?php echo $transDetailsResponse->PaymentTransactionDetails->PayerInfo->Payer; ?></td>
</tr>
<tr class="row-data unread_new">
<td>City Name</td>
<td><?php echo $transDetailsResponse->PaymentTransactionDetails->PayerInfo->Address->CityName; ?></td>
</tr>
<tr class="row-data unread_new">
<td>Country</td>
<td><?php echo $transDetailsResponse->PaymentTransactionDetails->PayerInfo->Address->Country; ?></td>
</tr>
</tbody>
</table>
</div>
<div class="fg-clear"></div>
<div class="col-md-12 nopadding">
<table id="results" >
<thead>
<tr class="head">
<th colspan="2">Product Information</th>
</tr>
</thead>
<tbody>
<tr class="row-data unread_new">
<td>Product Name</td>
<td><?php echo $transDetailsResponse->PaymentTransactionDetails->PaymentItemInfo->PaymentItem[0]->Name; ?></td>
</tr>
<tr class="row-data unread_new">
<td>Quantity</td>
<td><?php echo $transDetailsResponse->PaymentTransactionDetails->PaymentItemInfo->PaymentItem[0]->Quantity; ?></td>
</tr>
<tr class="row-data unread_new">
<td>GrossAmount</td>
<td><?php echo $transDetailsResponse->PaymentTransactionDetails->PaymentInfo->GrossAmount->value; ?></td>
</tr>
<tr class="row-data unread_new">
<td>currency Type</td>
<td><?php echo $transDetailsResponse->PaymentTransactionDetails->PaymentInfo->GrossAmount->currencyID; ?></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="col-md-12 nopadding">
<form action="refund-process.php" method="POST">
<table id="results" >
<thead>
<tr class="head">
<th>Refund Detail</th>
</tr>
</thead>
<tbody>
<tr class="row-data unread_new">
<td>
<div class="fg-row">

</div>
<div class="fg-row" style=" margin-right: 3%;">
<div class="col-md-4 nopadding">
<label class="block fg-label">Refund Type</label>
<select class="fg-select fg-fw" name="refundType" id="refundType">
<option value="Full">Full Amount</option>
<option value="Partial">Partial Amount</option>
</select>
<p class="fg-help"></p>
</div>
<div class="col-md-4 nopadding">
<div style="margin-left: 5%;">
<input type="hidden" value="<?php echo $_POST['transID']; ?>" name="transID">
<label class="block fg-label">Amount</label>
<input class="fg-fw text fg-input" placeholder="" name="amt" type="number" step=".1" id="amt" value="" readonly="true">
<p class="fg-help"></p>
</div>
</div>
<div class="col-md-4 nopadding">
<div style="margin-left: 5%;">
<input type="hidden" value="<?php echo $currency_value; ?>" name="currencyID">
<label class="block fg-label">Currency Code</label>
<select class="fg-select fg-fw" disabled="true">
<option value="USD/$" title="$" <?php echo $currency_value == 'USD' ? 'selected' : ''; ?>>USD</option>
<option value="AUD/$" title="$" <?php echo $currency_value == 'AUD' ? 'selected' : ''; ?>>AUD</option>
<option value="BRL/R$" title="R$" <?php echo $currency_value == 'BRL' ? 'selected' : ''; ?>>BRL</option>
<option value="GBP/£" title="£" <?php echo $currency_value == 'GBP' ? 'selected' : ''; ?>>GBP</option>
<option value="CAD/$" title="$" <?php echo $currency_value == 'CAD' ? 'selected' : ''; ?>>CAD</option>
<option value="CZK/" title=""<?php echo $currency_value == 'CZK' ? 'selected' : ''; ?>>CZK</option>
<option value="DKK/" title=""<?php echo $currency_value == 'DKK' ? 'selected' : ''; ?>>DKK</option>
<option value="EUR/€" title="€"<?php echo $currency_value == 'EUR' ? 'selected' : ''; ?>>EUR</option>
<option value="HKD/$" title="$"<?php echo $currency_value == 'HKD' ? 'selected' : ''; ?>>HKD</option>
<option value="HUF/" title=""<?php echo $currency_value == 'HUF' ? 'selected' : ''; ?>>HUF</option>
<option value="ILS/₪" title="₪"<?php echo $currency_value == 'ILS' ? 'selected' : ''; ?>>ILS</option>
<option value="JPY/¥" title="¥"<?php echo $currency_value == 'JPY' ? 'selected' : ''; ?>>JPY</option>
<option value="MXN/$" title="$"<?php echo $currency_value == 'MXN' ? 'selected' : ''; ?>>MXN</option>
<option value="TWD/NT$" title="NT$"<?php echo $currency_value == 'TWD' ? 'selected' : ''; ?>>TWD</option>
<option value="NZD/$" title="$"<?php echo $currency_value == 'NZD' ? 'selected' : ''; ?>>NZD</option>
<option value="NOK/" title=""<?php echo $currency_value == 'NOK' ? 'selected' : ''; ?>>NOK</option>
<option value="PHP/P" title="P"<?php echo $currency_value == 'PHP' ? 'selected' : ''; ?>>PHP</option>
<option value="PLN/" title=""<?php echo $currency_value == 'PLN' ? 'selected' : ''; ?>>PLN</option>
<option value="RUB/" title=""<?php echo $currency_value == 'RUB' ? 'selected' : ''; ?>>RUB</option>
<option value="SGD/$" title="$"<?php echo $currency_value == 'SGD' ? 'selected' : ''; ?>>SGD</option>
<option value="SEK/" title=""<?php echo $currency_value == 'SEK' ? 'selected' : ''; ?>>SEK</option>
<option value="CHF/" title=""<?php echo $currency_value == 'CHF' ? 'selected' : ''; ?>>CHF</option>
<option value="THB/฿" title="฿"<?php echo $currency_value == 'THB' ? 'selected' : ''; ?>>THB</option>
</select>
<p class="fg-help"></p>
</div>
</div>
<div class="fg-clear"></div>
</div>
<div class="fg-row" style=" margin-right: 3%;">
<label class="block fg-label">Note</label>
<textarea class="fg-textarea fg-fw last" rows="6" name="memo"></textarea>
<p class="fg-help"></p>
<div class="fg-clear"></div>
</div>
<div class="fg-row" style=" margin-right: 3%;">
<input type="hidden" name="retryUntil" value="">
<input type="hidden" name="refundSource" value="any">
<input type="submit" value="Refund" name="RefundBtn" id="submit">
<div class="fg-clear"></div>
</div>
</td>
</tr>
</tbody>
</table>
</form>
</div>
<?php
}
}
?>
</div>
<img id="paypal_logo" src="images/secure-paypal-logo.jpg">
</div>
<div id="pop2" class="simplePopup">
<div id="loader">
<div id="circularG">
<div id="circularG_1" class="circularG">
</div>
<div id="circularG_2" class="circularG">
</div>
<div id="circularG_3" class="circularG">
</div>
<div id="circularG_4" class="circularG">
</div>
<div id="circularG_5" class="circularG">
</div>
<div id="circularG_6" class="circularG">
</div>
<div id="circularG_7" class="circularG">
</div>
<div id="circularG_8" class="circularG">
</div>
</div>
</div>
</div>
<script src="js/jquery.min.js"></script>
<script src="js/jquery.simplePopup.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
$('input#amt').val('<?php
if (!empty($transDetailsResponse->PaymentTransactionDetails->PaymentInfo->GrossAmount->value)) {
echo $transDetailsResponse->PaymentTransactionDetails->PaymentInfo->GrossAmount->value;
}
?>');
$('input#amt').css({'background-color': '#F1F1F1'});
$('input#submit').click(function() {
$('#pop2').simplePopup();
});
$('#refundType').on('change', function() {
if (this.value == 'Full') {
$('input#amt').css({'background-color': '#F1F1F1'});
$('input#amt').val('<?php
if (!empty($transDetailsResponse->PaymentTransactionDetails->PaymentInfo->GrossAmount->value)) {
echo $transDetailsResponse->PaymentTransactionDetails->PaymentInfo->GrossAmount->value;
}
?>');
$('input#amt').prop("readonly", true);
} else if (this.value == 'Partial') {
$('input#amt').css({'background-color': 'white'});
$('input#amt').prop("readonly", false);
}
});
});
</script>
</body>
</html>

 

Refund-process.php

refund-process.php file gets array data from the index.php, where array contains refund details and this array, will used for a process to PayPal. After completing refund process, PayPal send response array to refund-process.php.



<?php
require_once('../PPBootStrap.php');
/*
* The RefundTransaction API operation issues a refund to the PayPal account holder associated with a transaction.
This sample code uses Merchant PHP SDK to make API call
*/
$refundReqest = new RefundTransactionRequestType();
/*
* Type of refund you are making. It is one of the following values:
* `Full` - Full refund (default).
* `Partial` - Partial refund.
*/
if ($_REQUEST['amt'] != "" && strtoupper($_POST['refundType']) != "FULL") {
/*
* `Refund amount`, which contains
* `Currency Code`
* `Amount`
The amount is required if RefundType is Partial.
`Note:
If RefundType is Full, do not set the amount.`
*/
$refundReqest->Amount = new BasicAmountType($_REQUEST['currencyID'], $_REQUEST['amt']);
}
$refundReqest->RefundType = $_REQUEST['refundType'];
/*
* Either the `transaction ID` or the `payer ID` must be specified.
PayerID is unique encrypted merchant identification number
For setting `payerId`,
`refundTransactionRequest.setPayerID("A9BVYX8XCR9ZQ");`
Unique identifier of the transaction to be refunded.
*/
$refundReqest->TransactionID = $_REQUEST['transID'];
$refundReqest->RefundSource = $_REQUEST['refundSource'];
$refundReqest->Memo = $_REQUEST['memo'];
$refundReqest->RetryUntil = $_REQUEST['retryUntil'];
$refundReq = new RefundTransactionReq();
$refundReq->RefundTransactionRequest = $refundReqest;
/*
* ## Creating service wrapper object
Creating service wrapper object to make API call and loading
Configuration::getAcctAndConfig() returns array that contains credential and config parameters
*/
$paypalService = new PayPalAPIInterfaceServiceService(Configuration::getAcctAndConfig());
try {
/* wrap API method calls on the service object with a try catch */
$refundResponse = $paypalService->RefundTransaction($refundReq);
} catch (Exception $ex) {
include_once("../Error.php");
exit;
}
if (isset($refundResponse)) {
?>
<html>
<head>
<title>Paypal Settlements and Refunds in PHP</title>
<link rel="stylesheet" type="text/css" href="css/style.css">
<meta name="robots" content="noindex, nofollow">
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-43981329-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script');
ga.type = 'text/javascript';
ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s);
})();
</script>
</head>
<body>

<div id="main">
<div class="success_main_heading">
<h1>Paypal Settlements and Refunds in PHP</h1>
</div>
<div id="return">
<h2>Refund Status</h2>
<hr/>

<?php
//Rechecking the product price and currency details
if ($refundResponse->Ack == 'Success') {
echo "<h3 id='success'>Refund Successful</h3>";
echo "<P>Gross Refund Amount - " . $refundResponse->GrossRefundAmount->value . " (" . $refundResponse->GrossRefundAmount->currencyID . ")</P>";
echo "<P>Refund Transaction ID - " . $refundResponse->RefundTransactionID . "</P>";

echo "<div class='back_btn'><a href='index.php' id= 'btn'><< Back </a></div>";
} else {
echo "<h3 id='fail'>Refund - Failed</h3>";
echo "<P>Error Message -" . $refundResponse->Errors[0]->LongMessage . "</P>";
echo "<div class='back_btn'><a href='index.php' id= 'btn'><< Back </a></div>";
}
?>
</div>
<!-- Right side div -->
<div class="fr"id="formget">
<a href=https://www.formget.com/app><img style="margin-left: 12%;" src="images/formget.jpg" alt="Online Form Builder"/></a>
</div>
</div>
</body>
</html>
<?php
}

Style.css

Includes basic styling of HTML elements.

@import url(http://fonts.googleapis.com/css?family=Raleway);
h1{
text-align: center;
}
#main {
width: 950PX;
margin: 50PX auto;
font-family: raleway;
}
#container {
width: 950px;
float: left;
border-radius: 10px;
font-family: raleway;
border: 2px solid #ccc;
padding: 10px 40px 11px;
margin-top: 16px;
}
h2 {
background-color: #FEFFED;
text-align: center;
border-radius: 10px 10px 0 0;
margin: -10px -40px;
padding: 15px;
}
hr {
border: 0;
border-bottom: 1px solid #ccc;
margin: 10px -40px;
margin-bottom: 30px;
}
input[type=text]{
margin-top: 6px;
line-height: normal;
padding: 9px 5px 8px 10px;
font-family: "proxima_nova_rgregular", sans-serif;
font-size: 16px;
}
input[type=submit] {
margin-left: 1%;
background-color: #FFBC00;
color: white;
border: 1px solid #FFCB00;
padding: 10px;
font-size: 17px;
cursor: pointer;
border-radius: 5px;
}
.fg-upload-parent {
position: relative;
margin-top: 6px;
}
.fg-row {
line-height: 1;
margin-bottom: 30px;
}
.fg-label {
color: #333333;
font-family: "proxima_novasemibold", sans-serif;
font-size: 16px;
line-height: 1;
}

.fg-clear {
clear: both;
}
.fg-help {
font-size: 13px;
line-height: 18px;
margin-top: 4px;
margin-left: 3px;
margin-bottom: 0;
color: #aaa;
display: block;
}

#results {
width: 100%;
margin-top: 30px;
border: 1px solid #ccc;
table-layout: fixed;
margin-bottom: 30px;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
thead {
display: table-header-group;
vertical-align: middle;
border-color: inherit;
}
.head {
font-size: 15px;
font-family: "proxima_novasemibold", sans-serif;
background: #FEFFED;
color: #1d4c55;
}
tr {
display: table-row;
vertical-align: inherit;
border-color: inherit;
}
.head th{
border-right: 1px solid #ccc;
border-bottom: 1px solid #ccc;
line-height: normal;
padding: 10px 0px;
text-align: center;
}
td {
border-right: 1px solid #ccc;
border-bottom: 1px solid #ccc;
line-height: normal;
padding: 10px 0px;
text-align: left;
padding-left:3%;
}

tbody {
display: table-row-group;
vertical-align: middle;
border-color: inherit;
}
tr {
display: table-row;
vertical-align: inherit;
border-color: inherit;
}
.fg-label {
color: #333333;
font-family: "proxima_novasemibold", sans-serif;
font-size: 18px;
line-height: 1;
}
.fg-label a{
color: #428bca;
text-decoration: none;
}

#return {
width: 492px;
height: 350px;
float: left;
border-radius: 10px;
font-family: raleway;
border: 2px solid #ccc;
padding: 10px 40px 11px;
}
#return h3#success {
text-align: center;
font-size: 24px;
margin-top: 50px;
color: green;
}
#return P {
text-align: center;
}
#return .back_btn {
margin-top: 51px;
text-align: center;
}
#btn {
width: 100%;
background-color: #FFBC00;
color: white;
border: 2px solid #FFCB00;
padding: 10px 70px;
font-size: 20px;
cursor: pointer;
border-radius: 5px;
margin-bottom: 15px;
margin: 0 auto;
}
a{
text-decoration:none;
color: cornflowerblue;
}
img#paypal_logo {
float: right;
margin-right: 20px;
margin-top: 1%;
padding-bottom: 15px;
}
.success_main_heading{
margin-left: -32%;
margin-bottom: 7%;

}
#return h3#fail{
text-align: center;
font-size: 24px;
margin-top: 50px;
color: red;
}
.red{
color:red;
font-weight: bold;
}
.fg-input, .fg-select, .fg-textarea {
padding-left: 5px;
border: 1px solid #bbbbbb;
border-radius: 3px;
font-family: "proxima_nova_rgregular", sans-serif;
font-size: 16px;
color: #383838;
}
.fg-fw {
width: 100%;
}
.fg-select {
margin-top: 6px;
padding: 8px 0 7px;
}
.text, .password {
margin-top: 6px;
line-height: normal;
padding: 9px 5px 8px 10px;
font-family: "proxima_nova_rgregular", sans-serif;
font-size: 16px;
}

 

Conclusion :

After reading the above post, I am sure you will give a try to the script provided and implement it in your own projects as well. Feel free to visit our website again in the future to get in touch with new coding tricks. You can let us know about your feedback in the space provided below :)