Created
February 8, 2018 06:02
-
-
Save NazmusShakib/acfc34dbc5bfb35fded64ee38ba6010c to your computer and use it in GitHub Desktop.
Custom WooCommerce PayPal Gateway
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Plugin Name: Custom WooCommerce PayPal Gateway | |
*/ | |
/** NOTES | |
* Downlaod Paypal SDK: https://github.com/paypal/PayPal-PHP-SDK/releases | |
* I have download it from https://github.com/paypal/PayPal-PHP-SDK/releases/download/1.7.4/PayPal-PHP-SDK-1.7.4.zip here | |
* Extract this in your plugin directory > includes > paypal-sdk | |
* Then need to configure Paypal app https://developer.paypal.com/developer/applications/ | |
* Once you have created you App, click on it. You will see your client ID and secret. | |
Copy them and paste them inside the WooCommerce > Settings > Checkout > Woo PayPal. | |
* And now its ready to work. | |
* | |
* Thanks! | |
*/ | |
defined( 'ABSPATH' ) or exit; | |
// Make sure WooCommerce is active | |
if ( ! in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) { | |
return; | |
} | |
/** | |
* Add the gateway to WC Available Gateways | |
* | |
* @since 1.0.0 | |
* @param array $gateways all available WC gateways | |
* @return array $gateways all WC gateways + offline gateway | |
*/ | |
function wc_paypal_add_to_gateways( $gateways ) { | |
$gateways[] = 'Woo_PayPal_Gateway'; | |
return $gateways; | |
} | |
add_filter( 'woocommerce_payment_gateways', 'wc_paypal_add_to_gateways' ); | |
use PayPal\Rest\ApiContext; | |
use PayPal\Auth\OAuthTokenCredential; | |
use PayPal\Api\Amount; | |
use PayPal\Api\Details; | |
use PayPal\Api\ExecutePayment; | |
use PayPal\Api\Item; | |
use PayPal\Api\ItemList; | |
use PayPal\Api\Payer; | |
use PayPal\Api\Payment; | |
use PayPal\Api\PaymentExecution; | |
use PayPal\Api\RedirectUrls; | |
use PayPal\Api\Transaction; | |
define('WOO_PAYMENT_DIR', plugin_dir_path(__FILE__)); | |
add_action('plugins_loaded', 'woo_payment_gateway', 12); | |
function woo_payment_gateway() { | |
class Woo_PayPal_Gateway extends WC_Payment_Gateway { | |
/** | |
* API Context used for PayPal Authorization | |
* @var null | |
*/ | |
public $apiContext = null; | |
/** | |
* Constructor for your shipping class | |
* | |
* @access public | |
* @return void | |
*/ | |
public function __construct() { | |
$this->id = 'woo_paypalll'; | |
$this->method_title = __( 'Woo PayPal', 'woodev_payment' ); | |
$this->method_description = __( 'WooCommerce PayPal Payment Gateway.', 'woo_paypal' ); | |
$this->title = __( 'Woo PayPal', 'woo_paypal' ); | |
$this->has_fields = false; | |
$this->supports = array( | |
'products' | |
); | |
$this->get_paypal_sdk(); | |
// Load the settings. | |
$this->init_form_fields(); | |
$this->init_settings(); | |
$this->enabled = $this->get_option('enabled'); | |
add_action( 'check_woopaypal', array( $this, 'check_response') ); | |
// Save settings | |
if ( is_admin() ) { | |
// Versions over 2.0 | |
// Save our administration options. Since we are not going to be doing anything special | |
// we have not defined 'process_admin_options' in this class so the method in the parent | |
// class will be used instead | |
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) ); | |
} | |
} | |
private function get_paypal_sdk() { | |
require_once WOO_PAYMENT_DIR . 'includes/paypal-sdk/autoload.php'; | |
} | |
public function init_form_fields() { | |
$this->form_fields = array( | |
'enabled' => array( | |
'title' => __( 'Enable', 'woo_paypal' ), | |
'type' => 'checkbox', | |
'label' => __( 'Enable WooPayPal', 'woo_paypal' ), | |
'default' => 'yes' | |
), | |
'client_id' => array( | |
'title' => __( 'Client ID', 'woo_paypal' ), | |
'type' => 'text', | |
'default' => '' | |
), | |
'client_secret' => array( | |
'title' => __( 'Client Secret', 'woo_paypal' ), | |
'type' => 'password', | |
'default' => '' | |
), | |
); | |
} | |
private function get_api_context() { | |
$client_id = $this->get_option('client_id'); | |
$client_secret = $this->get_option('client_secret'); | |
$this->apiContext = new ApiContext(new OAuthTokenCredential( | |
$client_id, | |
$client_secret | |
)); | |
} | |
public function process_payment( $order_id ) { | |
global $woocommerce; | |
$order = new WC_Order( $order_id ); | |
$this->get_api_context(); | |
$payer = new Payer(); | |
$payer->setPaymentMethod("paypal"); | |
$all_items = array(); | |
$subtotal = 0; | |
// Products | |
foreach ( $order->get_items( array( 'line_item', 'fee' ) ) as $item ) { | |
$itemObject = new Item(); | |
$itemObject->setCurrency( get_woocommerce_currency() ); | |
if ( 'fee' === $item['type'] ) { | |
$itemObject->setName( __( 'Fee', 'woo_paypal' ) ); | |
$itemObject->setQuantity(1); | |
$itemObject->setPrice( $item['line_total'] ); | |
$subtotal += $item['line_total']; | |
} else { | |
$product = $order->get_product_from_item( $item ); | |
$sku = $product ? $product->get_sku() : ''; | |
$itemObject->setName( $item['name'] ); | |
$itemObject->setQuantity( $item['qty'] ); | |
$itemObject->setPrice( $order->get_item_subtotal( $item, false ) ); | |
$subtotal += $order->get_item_subtotal( $item, false ) * $item['qty']; | |
if( $sku ) { | |
$itemObject->setSku( $sku ); | |
} | |
} | |
$all_items[] = $itemObject; | |
} | |
$itemList = new ItemList(); | |
$itemList->setItems( $all_items ); | |
// ### Additional payment details | |
// Use this optional field to set additional | |
// payment information such as tax, shipping | |
// charges etc. | |
$details = new Details(); | |
$details->setShipping( $order->get_total_shipping() ) | |
->setTax( $order->get_total_tax() ) | |
->setSubtotal( $subtotal ); | |
$amount = new Amount(); | |
$amount->setCurrency( get_woocommerce_currency() ) | |
->setTotal( $order->get_total() ) | |
->setDetails($details); | |
$transaction = new Transaction(); | |
$transaction->setAmount($amount) | |
->setItemList($itemList) | |
->setInvoiceNumber(uniqid()); | |
$baseUrl = $this->get_return_url( $order ); | |
if( strpos( $baseUrl, '?') !== false ) { | |
$baseUrl .= '&'; | |
} else { | |
$baseUrl .= '?'; | |
} | |
$redirectUrls = new RedirectUrls(); | |
$redirectUrls->setReturnUrl( $baseUrl . 'woopaypal=true&order_id=' . $order_id ) | |
->setCancelUrl( $baseUrl . 'woopaypal=cancel&order_id=' . $order_id ); | |
$payment = new Payment(); | |
$payment->setIntent("sale") | |
->setPayer($payer) | |
->setRedirectUrls($redirectUrls) | |
->setTransactions(array($transaction)); | |
try { | |
$payment->create($this->apiContext); | |
$approvalUrl = $payment->getApprovalLink(); | |
return array( | |
'result' => 'success', | |
'redirect' => $approvalUrl | |
); | |
} catch (Exception $ex) { | |
wc_add_notice( $ex->getMessage(), 'error' ); | |
} | |
return array( | |
'result' => 'failure', | |
'redirect' => '' | |
); | |
} | |
public function check_response() { | |
global $woocommerce; | |
if( isset( $_GET['woopaypal'] ) ) { | |
$woopaypal = $_GET['woopaypal']; | |
$order_id = $_GET['order_id']; | |
if( $order_id == 0 || $order_id == '' ) { | |
return; | |
} | |
$order = new WC_Order( $order_id ); | |
if( $order->has_status('completed') || $order->has_status('processing')) { | |
return; | |
} | |
if( $woopaypal == 'true' ) { | |
$this->get_api_context(); | |
$paymentId = $_GET['paymentId']; | |
$payment = Payment::get($paymentId, $this->apiContext); | |
$execution = new PaymentExecution(); | |
$execution->setPayerId($_GET['PayerID']); | |
$transaction = new Transaction(); | |
$amount = new Amount(); | |
$details = new Details(); | |
$subtotal = 0; | |
// Products | |
foreach ( $order->get_items( array( 'line_item', 'fee' ) ) as $item ) { | |
if ( 'fee' === $item['type'] ) { | |
$subtotal += $item['line_total']; | |
} else { | |
$subtotal += $order->get_item_subtotal( $item, false ) * $item['qty']; | |
} | |
} | |
$details->setShipping( $order->get_total_shipping() ) | |
->setTax( $order->get_total_tax() ) | |
->setSubtotal( $subtotal ); | |
$amount = new Amount(); | |
$amount->setCurrency( get_woocommerce_currency() ) | |
->setTotal( $order->get_total() ) | |
->setDetails($details); | |
$transaction->setAmount($amount); | |
$execution->addTransaction($transaction); | |
try { | |
$result = $payment->execute($execution, $this->apiContext); | |
} catch (Exception $ex) { | |
$data = json_decode( $ex->getData()); | |
wc_add_notice( $ex->getMessage(), 'error' ); | |
$order->update_status('failed', sprintf( __( '%s payment failed! Transaction ID: %d', 'woocommerce' ), $this->title, $paymentId ) . ' ' . $ex->getMessage() ); | |
return; | |
} | |
// Payment complete | |
$order->payment_complete( $paymentId ); | |
// Add order note | |
$order->add_order_note( sprintf( __( '%s payment approved! Trnsaction ID: %s', 'woocommerce' ), $this->title, $paymentId ) ); | |
// Remove cart | |
$woocommerce->cart->empty_cart(); | |
} | |
if( $woopaypal == 'cancel' ) { | |
$order = new WC_Order( $order_id ); | |
$order->update_status('cancelled', sprintf( __( '%s payment cancelled! Transaction ID: %d', 'woocommerce' ), $this->title, $paymentId ) ); | |
} | |
} | |
return; | |
} | |
} | |
} | |
add_action( 'init', 'check_for_woopaypal' ); | |
function check_for_woopaypal() { | |
if( isset($_GET['woopaypal'])) { | |
// Start the gateways | |
WC()->payment_gateways(); | |
do_action( 'check_woopaypal' ); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment