Skip to content

Instantly share code, notes, and snippets.

@pippinsplugins
Created May 31, 2012 15:31
Show Gist options
  • Save pippinsplugins/2844181 to your computer and use it in GitHub Desktop.
Save pippinsplugins/2844181 to your computer and use it in GitHub Desktop.
New PayPal Standard for EDD
<?php
/**
* PayPal Standard Gateway
*
* @package Easy Digital Downloads
* @subpackage PayPal Standard Gateway
* @copyright Copyright (c) 2012, Pippin Williamson
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 1.0
*/
/**
* PayPal Remove CC Form
*
* PayPal Standard does not need a CC form, so remove it.
*
* @access private
* @since 1.0
* @return void
*/
function edd_paypal_remove_cc_form() {
// we only register the action so that the default CC form is not shown
}
add_action( 'edd_paypal_cc_form', 'edd_paypal_remove_cc_form' );
/**
* Process PayPal Purchase
*
* @access private
* @since 1.0
* @return void
*/
function edd_process_paypal_purchase( $purchase_data ) {
global $edd_options;
// check there is a gateway name
if ( ! isset( $purchase_data['post_data']['edd-gateway'] ) )
return;
/*
Purchase data comes in like this:
////////////////////////////////
$purchase_data = array(
'downloads' => array of download IDs,
'price' => total price of cart contents,
'purchase_key' => // random key
'user_email' => $user_email,
'date' => date( 'Y-m-d H:i:s' ),
'user_id' => $user_id,
'post_data' => $_POST,
'user_info' => array of user's information and used discount code
'cart_details' => array of cart details,
);
*/
// collect payment data
$payment_data = array(
'price' => $purchase_data['price'],
'date' => $purchase_data['date'],
'user_email' => $purchase_data['user_email'],
'purchase_key' => $purchase_data['purchase_key'],
'currency' => $edd_options['currency'],
'downloads' => $purchase_data['downloads'],
'user_info' => $purchase_data['user_info'],
'cart_details' => $purchase_data['cart_details'],
'status' => 'pending'
);
// record the pending payment
$payment = edd_insert_payment( $payment_data );
// check payment
if ( ! $payment ) {
// problems? send back
edd_send_back_to_checkout( '?payment-mode=' . $purchase_data['post_data']['edd-gateway'] );
} else {
// only send to PayPal if the pending payment is created successfully
$listener_url = trailingslashit( home_url() ).'?edd-listener=IPN';
// get the success url
$return_url = add_query_arg( 'payment-confirmation', 'paypal', get_permalink( $edd_options['success_page'] ) );
// get the complete cart summary
$cart_summary = edd_get_purchase_summary( $purchase_data, false );
// get the PayPal redirect uri
$paypal_redirect = trailingslashit( edd_get_paypal_redirect() ) . '?';
// setup PayPal arguments
$paypal_args = array(
'cmd' => '_xclick',
'amount' => $purchase_data['price'],
'business' => $edd_options['paypal_email'],
'item_name' => $cart_summary,
'email' => $purchase_data['user_email'],
'no_shipping' => '1',
'no_note' => '1',
'currency_code' => $edd_options['currency'],
'item_number' => $purchase_data['purchase_key'],
'charset' => 'UTF-8',
'custom' => $payment,
'rm' => '2',
'return' => $return_url,
'notify_url' => $listener_url
);
// build query
$paypal_redirect .= http_build_query( $paypal_args );
// get rid of cart contents
edd_empty_cart();
// Redirect to PayPal
wp_redirect( $paypal_redirect );
exit;
}
}
add_action( 'edd_gateway_paypal', 'edd_process_paypal_purchase' );
/**
* Listen For PayPal IPN
*
* Listens for a PayPal IPN requests and then sends to the processing function.
*
* @access private
* @since 1.0
* @return void
*/
function edd_listen_for_paypal_ipn() {
global $edd_options;
// regular PayPal IPN
if ( ! isset( $edd_options['paypal_alternate_verification'] ) ) {
if ( isset( $_GET['edd-listener'] ) && $_GET['edd-listener'] == 'IPN' ) {
do_action( 'edd_verify_paypal_ipn' );
}
// alternate purchase verification
} else {
if ( isset( $_GET['tx'] ) && isset( $_GET['st'] ) && isset( $_GET['amt'] ) && isset( $_GET['cc'] ) && isset( $_GET['cm'] ) && isset( $_GET['item_number'] ) ) {
// we are using the alternate method of verifying PayPal purchases
// setup each of the variables from PayPal
$payment_status = $_GET['st'];
$paypal_amount = $_GET['amt'];
$payment_id = $_GET['cm'];
$purchase_key = $_GET['item_number'];
$currency = $_GET['cc'];
// retrieve the meta info for this payment
$payment_meta = get_post_meta( $payment_id, '_edd_payment_meta', true );
$payment_amount = edd_format_amount( $payment_meta['amount'] );
if ( $currency != $edd_options['currency'] ) {
return; // the currency code is invalid
}
if ( $paypal_amount != $payment_amount ) {
return; // the prices don't match
}
if ( $purchase_key != $payment_meta['key'] ) {
return; // purchase keys don't match
}
if ( strtolower( $payment_status ) != 'completed' || edd_is_test_mode() ) {
return; // payment wasn't completed
}
// everything has been verified, update the payment to "complete"
edd_update_payment_status( $payment_id, 'publish' );
}
}
}
add_action( 'init', 'edd_listen_for_paypal_ipn' );
/**
* Process PayPal IPN
*
* @access private
* @since 1.0
* @return void
*/
function edd_process_paypal_ipn() {
global $edd_options;
// check the request method is POST
if ( isset( $_SERVER['REQUEST_METHOD'] ) && $_SERVER['REQUEST_METHOD'] != 'POST' ) {
return;
}
// set initial post data to false
$post_data = false;
// fallback just in case post_max_size is lower than needed
if ( ini_get( 'allow_url_fopen' ) )
$post_data = file_get_contents( 'php://input' );
// start the encoded data collection with notification command
$encoded_data = 'cmd=_notify-validate';
// verify there is a post_data
if ( $post_data || strlen( $post_data ) > 0 ) {
// append the data
$encoded_data .= '&'.$post_data;
} else {
// check if POST is empty
if ( empty( $_POST ) ) {
// nothing to do
return;
} else {
// loop trough each POST
foreach ( $_POST as $key => $value ) {
// encode the value and append the data
$encoded_data .= "&$key=" . urlencode( $value );
}
}
}
// convert collected post data to an array
parse_str( $encoded_data, $encoded_data_array );
// get the PayPal redirect uri
$paypal_redirect = edd_get_paypal_redirect(true);
$remote_post_vars = array(
'method' => 'POST',
'timeout' => 45,
'redirection' => 5,
'httpversion' => '1.0',
'blocking' => true,
'headers' => array(),
'body' => $encoded_data_array
);
// get response
$api_response = wp_remote_post( edd_get_paypal_redirect(), $remote_post_vars );
if ($api_response['body'] !== 'VERIFIED')
return; // response not okay
// convert collected post data to an array
parse_str( $post_data, $post_data_array );
// check if $post_data_array has been populated
if ( ! is_array( $post_data_array ) && ! empty( $post_data_array ) )
return;
// collect payment details
$payment_id = $post_data_array['custom'];
$purchase_key = $post_data_array['item_number'];
$paypal_amount = $post_data_array['mc_gross'];
$payment_status = $post_data_array['payment_status'];
$currency_code = strtolower( $post_data_array['mc_currency'] );
// retrieve the meta info for this payment
$payment_meta = get_post_meta( $payment_id, '_edd_payment_meta', true );
$payment_amount = edd_format_amount( $payment_meta['amount'] );
// verify details
if ( $currency_code != strtolower( $edd_options['currency'] ) ) {
// the currency code is invalid
return;
}
if ( $paypal_amount != $payment_amount ) {
// the prices don't match
return;
}
if ( $purchase_key != $payment_meta['key'] ) {
// purchase keys don't match
return;
}
if ( isset( $post_data_array['txn_type'] ) && $post_data_array['txn_type'] == 'web_accept' ) {
$status = strtolower( $payment_status );
if ( $status == 'completed' || edd_is_test_mode() ) {
edd_update_payment_status( $payment_id, 'publish' );
}
}
}
add_action( 'init', 'edd_process_paypal_ipn' );
/**
* Get Paypal Redirect
*
* @access private
* @since 1.0.8.2
* @return string
*/
function edd_get_paypal_redirect( $ssl_check = false ) {
global $edd_options;
if( is_ssl() || ! $ssl_check ) {
$protocal = 'https://';
} else {
$protocal = 'http://';
}
// check the current payment mode
if ( edd_is_test_mode() ) {
// test mode
$paypal_uri = $protocal . 'www.sandbox.paypal.com/cgi-bin/webscr';
} else {
// live mode
$paypal_uri = $protocal . 'www.paypal.com/cgi-bin/webscr';
}
return $paypal_uri;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment