Introduction
In this article, we are going to share how to do the follows with PayPal REST API
- Create authorization order
- Authorization
- Capture
- Refund
- Place funds on hold
Since it’s a learning technical diary, it will contain my personal project. You could selectively refer to this article.
Install PayPal REST API official SDK
In this article, we use the latest released version of the official SDK
Install
composer require paypal/paypal-checkout-sdk |
Setting
Personal setting
After installation, you could find the example under SDK directory as photo below:
Configure
PayPal Client.php
as follows: 1. Apply for a developer account and login 2. Create an App 3. Get your Client ID and Secret
4. Fill in with the got Client ID and Secret, Ray set them as environment variables.
public static function environment() |
Let’s begin
As mentioned previously, we could find almost all of the examples for every situation in the official sample directory. You could customize it according to your need. The following will be Ray’s version.
If you have any questions, feel free to refer to the samples under sample
directory, and the official document as follows:
order
payment
The difference between order and payment
Here are some main differences:
- order: It only supports members of PayPal. You could delay your payment, and partially capture the payment upon what you need.
- payment: You could delay the payment, but you can’t partially capture it.
For more information, you could refer to the official document
Create an order
public function createOrder($toBeSavedInfo, Recipient $recipient, $debug = false) |
Please refer to the RequestBody for creating an order as follows:
public static function buildRequestBody($toBeSavedInfo, Recipient $recipient) |
Authorization
Now, we are going to use one of the important functions in REST API, authorization.
- After authorization, we will be able to capture the authorized amount within 29 days. However, PayPal only guarantees that the authorized amount will be available for three days right after a single authorization.
- It means that PayPal will temporarily place authorized funds on hold within buyer’s account for only three days after authorization. Please note that it’s only for three days, and it’s called Honor Period.
- After the first authorization, we will be able to apply for multiple authorization up to 10 times, which is called reauthorize
If you think the number is too less, you could contact PayPal, and raise the number to up to 99 times. - Actually if you count the time properly and precisely, 10-time authorization should be enough. If you authorize once every three days, you could place funds on hold for a month with 10-time authorization, which is even enough for sea fright.
- You will be allowed to change the order amount for up to 115% or not more than USD 75. You could use this feature when there are some required changes on tax or shipping fee.
- You could refer to official document
Here is the authorization example as follows.
Please note that it’s Ray’s version. You could refer to official version and then modify it according to your need, or make one on our own with a reference on its SDK, which I think might be the best solution.
/** |
After authorization, we need to check if the authorization is successful, and therefore Ray made a validation function with the response got from the SDK
public static function checkIfAuthorizedSuccessfully($response) |
Capture
- Just like mentioned above, we will be allowed to capture the order after a successful authorization.
- However, PayPal only guarantees the authorized amount will be available for three days, which is also called honor period.
- Generally speaking, a proper and precise time counting with authorization and reauthorizing will be able to temporarily place funds on hold for 30 days.
Here is the capture example
public static function captureAuthorization(NewPayPal $newPayPal, $final_capture = false, $debug = false) |
Here is RequestBody for capture.
public static function buildRequestBodyForCaptureAuthorization($amount = null, $final_capture = false, $currency = 'USD') |
Here is the logic of capture as follows:
Ray’s logic is to set a to-be-captured amount to decide when the amount will be captured, which could save handing fee because each time a refund request will cost some handing fee. So Ray’s logic is to place funds on hold, and only revise to-be-captured amount when a refund request is made before to-be-captured date. Therefore, we could at the most extend save the handing fee on the seller side. The allowable refund period is 7 days in Ray’s logic, and capture the authorization with the final to-be-captured amount.
So the following function only runs once a day. If the current time is beyond the to-be-captured date, the authorization will be captured and update order state accordingly.
public static function dailyCaptureAuthorization() |
Refund
- The rule of refund is to refund an amount of money partially or one-time towards specific authorization.
- If you specify an amount, you refund the order partially.
- If you would like to fund it at a time, you could leave a empty RequestBody as the official example.
public static function refundOrder($captureId, $amount, $currency, $debug = false)
{
$request = new CapturesRefundRequest($captureId);
// The required to-be-refunded amount and currency should match the ones of the authorization.
$request->body = self::buildRequestBodyForRefundOrder($amount, $currency);
$client = PayPalClient::client();
$response = $client->execute($request);
if ($debug)
{
print "Status Code: {$response->statusCode}\n";
print "Status: {$response->result->status}\n";
print "Order ID: {$response->result->id}\n";
print "Links:\n";
foreach ($response->result->links as $link)
{
print "\t{$link->rel}: {$link->href}\tCall Type: {$link->method}\n";
}
// To toggle printing the whole response body comment/uncomment below line
echo json_encode($response->result, JSON_PRETTY_PRINT), "\n";
}
return $response;
}
The following is the RequestBody for refund.
public static function buildRequestBodyForRefundOrder($amount = null, $currency = 'USD', $final_capture = false) |
The logic for refund.
- Corresponding to the capture action, before the seller make any capture to buyers, all those refund requests from buyers are only to revise numbers in the database.
- If 7 days have passed, but in a particular case, a refund request still raised by a buyer, the amount could still be refunded with inevitable handing fee.
- All logic mentioned above is only for PayPal. Since this project integrate with two payment gateway, the above mentioned logic doens’t suit AllPay. However, generally speaking, it makes no difference to buyers.
public static function refund(Order $order, NewPayPal $paymentServiceInstance, OrderRelations $orderRelation)
{
// When the order is authorized but not yet captured.
if (($paymentServiceInstance->capture_id === null) && ($paymentServiceInstance->authorization_id !== null))
{
// As mentioned above, we only revise to-be-captured amount in the database.
$paymentServiceInstance->update([
'to_be_captured_amount' => $paymentServiceInstance->to_be_captured_amount - $order->total_amount,
'total_amount' => $paymentServiceInstance->total_amount - $order->total_amount
]);
$order->update(['status' => 4]);
$orderRelation->update(['status' => 4]);
}
// When the order has been captured
if ($paymentServiceInstance->capture_id !== null)
{
// We do implement refund API, returning the amount to buyers.
$response = self::refundOrder($paymentServiceInstance->capture_id, $order->total_amount, $paymentServiceInstance->mc_currency);
// If the refund is completed, the order state will be updated.
if ($response->result->status == 'COMPLETED')
{
$order->update(['status' => 4]);
$orderRelation->update(['status' => 4]);
$paymentServiceInstance->update([
'total_amount' => $paymentServiceInstance->total_amount - $order->total_amount
]);
}
}
}
Cancel an authorization.
Cancelling an authorization is pretty easy with official example. You only have to provide authorization ID with required format, we are not going to explain explicitly.
The authorization ID will be returned after a successful authorization, so remember to save it.
Get authorization data.
Getting an authorization is pretty easy with official example. You only have to provide authorization ID with required format, we are not going to explain explicitly.
The authorization ID will be returned after a successful authorization, so remember to save it.
Getting capture data
Getting a capture data is pretty easy with official example. You only have to provide authorization ID with required format, we are not going to explain explicitly.
The capture ID will be returned after a successful authorization, so remember to save it.
Conclusion
According to the official document, you could use Smart Button of JavaScript SDK with PayPal REST APIO. However, Ray is responsible for backend, so this part wasn’t deeply dug.
It looks interesting. If you are interested, you could spend some time on it.
PayPal is veritably an international payment gateway. It provides various features and supports. What a pity that PayPal has taken back its service from Taiwan. However, as far as I know, it happened due to tax safeguarding in Taiwan. It’s hard to judge good or bad.
I’ve spent some time those days digging in PayPal gateway. Surely there are still some dedicate features that I haven’t tried. I will write another article for that after I give it a shot!
You are free to share this article wherever you want, but kindly cite the source. Thanks!
Comments