Added login request

This commit is contained in:
Nedim Uka
2018-06-20 18:03:43 +02:00
parent 4e52521fae
commit 593b445a21
4716 changed files with 1218265 additions and 57 deletions

View File

@@ -0,0 +1,441 @@
<?php
/**
* Class WC_Gateway_BACS file.
*
* @package WooCommerce\Gateways
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Bank Transfer Payment Gateway.
*
* Provides a Bank Transfer Payment Gateway. Based on code by Mike Pepper.
*
* @class WC_Gateway_BACS
* @extends WC_Payment_Gateway
* @version 2.1.0
* @package WooCommerce/Classes/Payment
*/
class WC_Gateway_BACS extends WC_Payment_Gateway {
/**
* Array of locales
*
* @var array
*/
public $locale;
/**
* Constructor for the gateway.
*/
public function __construct() {
$this->id = 'bacs';
$this->icon = apply_filters( 'woocommerce_bacs_icon', '' );
$this->has_fields = false;
$this->method_title = __( 'Direct bank transfer', 'woocommerce' );
$this->method_description = __( 'Take payments in person via BACS. More commonly known as direct bank/wire transfer', 'woocommerce' );
// Load the settings.
$this->init_form_fields();
$this->init_settings();
// Define user set variables.
$this->title = $this->get_option( 'title' );
$this->description = $this->get_option( 'description' );
$this->instructions = $this->get_option( 'instructions' );
// BACS account fields shown on the thanks page and in emails.
$this->account_details = get_option(
'woocommerce_bacs_accounts',
array(
array(
'account_name' => $this->get_option( 'account_name' ),
'account_number' => $this->get_option( 'account_number' ),
'sort_code' => $this->get_option( 'sort_code' ),
'bank_name' => $this->get_option( 'bank_name' ),
'iban' => $this->get_option( 'iban' ),
'bic' => $this->get_option( 'bic' ),
),
)
);
// Actions.
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'save_account_details' ) );
add_action( 'woocommerce_thankyou_bacs', array( $this, 'thankyou_page' ) );
// Customer Emails.
add_action( 'woocommerce_email_before_order_table', array( $this, 'email_instructions' ), 10, 3 );
}
/**
* Initialise Gateway Settings Form Fields.
*/
public function init_form_fields() {
$this->form_fields = array(
'enabled' => array(
'title' => __( 'Enable/Disable', 'woocommerce' ),
'type' => 'checkbox',
'label' => __( 'Enable bank transfer', 'woocommerce' ),
'default' => 'no',
),
'title' => array(
'title' => __( 'Title', 'woocommerce' ),
'type' => 'text',
'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ),
'default' => __( 'Direct bank transfer', 'woocommerce' ),
'desc_tip' => true,
),
'description' => array(
'title' => __( 'Description', 'woocommerce' ),
'type' => 'textarea',
'description' => __( 'Payment method description that the customer will see on your checkout.', 'woocommerce' ),
'default' => __( 'Make your payment directly into our bank account. Please use your Order ID as the payment reference. Your order will not be shipped until the funds have cleared in our account.', 'woocommerce' ),
'desc_tip' => true,
),
'instructions' => array(
'title' => __( 'Instructions', 'woocommerce' ),
'type' => 'textarea',
'description' => __( 'Instructions that will be added to the thank you page and emails.', 'woocommerce' ),
'default' => '',
'desc_tip' => true,
),
'account_details' => array(
'type' => 'account_details',
),
);
}
/**
* Generate account details html.
*
* @return string
*/
public function generate_account_details_html() {
ob_start();
$country = WC()->countries->get_base_country();
$locale = $this->get_country_locale();
// Get sortcode label in the $locale array and use appropriate one.
$sortcode = isset( $locale[ $country ]['sortcode']['label'] ) ? $locale[ $country ]['sortcode']['label'] : __( 'Sort code', 'woocommerce' );
?>
<tr valign="top">
<th scope="row" class="titledesc"><?php esc_html_e( 'Account details:', 'woocommerce' ); ?></th>
<td class="forminp" id="bacs_accounts">
<div class="wc_input_table_wrapper">
<table class="widefat wc_input_table sortable" cellspacing="0">
<thead>
<tr>
<th class="sort">&nbsp;</th>
<th><?php esc_html_e( 'Account name', 'woocommerce' ); ?></th>
<th><?php esc_html_e( 'Account number', 'woocommerce' ); ?></th>
<th><?php esc_html_e( 'Bank name', 'woocommerce' ); ?></th>
<th><?php echo esc_html( $sortcode ); ?></th>
<th><?php esc_html_e( 'IBAN', 'woocommerce' ); ?></th>
<th><?php esc_html_e( 'BIC / Swift', 'woocommerce' ); ?></th>
</tr>
</thead>
<tbody class="accounts">
<?php
$i = -1;
if ( $this->account_details ) {
foreach ( $this->account_details as $account ) {
$i++;
echo '<tr class="account">
<td class="sort"></td>
<td><input type="text" value="' . esc_attr( wp_unslash( $account['account_name'] ) ) . '" name="bacs_account_name[' . esc_attr( $i ) . ']" /></td>
<td><input type="text" value="' . esc_attr( $account['account_number'] ) . '" name="bacs_account_number[' . esc_attr( $i ) . ']" /></td>
<td><input type="text" value="' . esc_attr( wp_unslash( $account['bank_name'] ) ) . '" name="bacs_bank_name[' . esc_attr( $i ) . ']" /></td>
<td><input type="text" value="' . esc_attr( $account['sort_code'] ) . '" name="bacs_sort_code[' . esc_attr( $i ) . ']" /></td>
<td><input type="text" value="' . esc_attr( $account['iban'] ) . '" name="bacs_iban[' . esc_attr( $i ) . ']" /></td>
<td><input type="text" value="' . esc_attr( $account['bic'] ) . '" name="bacs_bic[' . esc_attr( $i ) . ']" /></td>
</tr>';
}
}
?>
</tbody>
<tfoot>
<tr>
<th colspan="7"><a href="#" class="add button"><?php esc_html_e( '+ Add account', 'woocommerce' ); ?></a> <a href="#" class="remove_rows button"><?php esc_html_e( 'Remove selected account(s)', 'woocommerce' ); ?></a></th>
</tr>
</tfoot>
</table>
</div>
<script type="text/javascript">
jQuery(function() {
jQuery('#bacs_accounts').on( 'click', 'a.add', function(){
var size = jQuery('#bacs_accounts').find('tbody .account').length;
jQuery('<tr class="account">\
<td class="sort"></td>\
<td><input type="text" name="bacs_account_name[' + size + ']" /></td>\
<td><input type="text" name="bacs_account_number[' + size + ']" /></td>\
<td><input type="text" name="bacs_bank_name[' + size + ']" /></td>\
<td><input type="text" name="bacs_sort_code[' + size + ']" /></td>\
<td><input type="text" name="bacs_iban[' + size + ']" /></td>\
<td><input type="text" name="bacs_bic[' + size + ']" /></td>\
</tr>').appendTo('#bacs_accounts table tbody');
return false;
});
});
</script>
</td>
</tr>
<?php
return ob_get_clean();
}
/**
* Save account details table.
*/
public function save_account_details() {
$accounts = array();
// phpcs:disable WordPress.CSRF.NonceVerification.NoNonceVerification -- Nonce verification already handled in WC_Admin_Settings::save()
if ( isset( $_POST['bacs_account_name'] ) && isset( $_POST['bacs_account_number'] ) && isset( $_POST['bacs_bank_name'] )
&& isset( $_POST['bacs_sort_code'] ) && isset( $_POST['bacs_iban'] ) && isset( $_POST['bacs_bic'] ) ) {
$account_names = wc_clean( wp_unslash( $_POST['bacs_account_name'] ) );
$account_numbers = wc_clean( wp_unslash( $_POST['bacs_account_number'] ) );
$bank_names = wc_clean( wp_unslash( $_POST['bacs_bank_name'] ) );
$sort_codes = wc_clean( wp_unslash( $_POST['bacs_sort_code'] ) );
$ibans = wc_clean( wp_unslash( $_POST['bacs_iban'] ) );
$bics = wc_clean( wp_unslash( $_POST['bacs_bic'] ) );
foreach ( $account_names as $i => $name ) {
if ( ! isset( $account_names[ $i ] ) ) {
continue;
}
$accounts[] = array(
'account_name' => $account_names[ $i ],
'account_number' => $account_numbers[ $i ],
'bank_name' => $bank_names[ $i ],
'sort_code' => $sort_codes[ $i ],
'iban' => $ibans[ $i ],
'bic' => $bics[ $i ],
);
}
}
// phpcs:enable
update_option( 'woocommerce_bacs_accounts', $accounts );
}
/**
* Output for the order received page.
*
* @param int $order_id Order ID.
*/
public function thankyou_page( $order_id ) {
if ( $this->instructions ) {
echo wp_kses_post( wpautop( wptexturize( wp_kses_post( $this->instructions ) ) ) );
}
$this->bank_details( $order_id );
}
/**
* Add content to the WC emails.
*
* @param WC_Order $order Order object.
* @param bool $sent_to_admin Sent to admin.
* @param bool $plain_text Email format: plain text or HTML.
*/
public function email_instructions( $order, $sent_to_admin, $plain_text = false ) {
if ( ! $sent_to_admin && 'bacs' === $order->get_payment_method() && $order->has_status( 'on-hold' ) ) {
if ( $this->instructions ) {
echo wp_kses_post( wpautop( wptexturize( $this->instructions ) ) . PHP_EOL );
}
$this->bank_details( $order->get_id() );
}
}
/**
* Get bank details and place into a list format.
*
* @param int $order_id Order ID.
*/
private function bank_details( $order_id = '' ) {
if ( empty( $this->account_details ) ) {
return;
}
// Get order and store in $order.
$order = wc_get_order( $order_id );
// Get the order country and country $locale.
$country = $order->get_billing_country();
$locale = $this->get_country_locale();
// Get sortcode label in the $locale array and use appropriate one.
$sortcode = isset( $locale[ $country ]['sortcode']['label'] ) ? $locale[ $country ]['sortcode']['label'] : __( 'Sort code', 'woocommerce' );
$bacs_accounts = apply_filters( 'woocommerce_bacs_accounts', $this->account_details );
if ( ! empty( $bacs_accounts ) ) {
$account_html = '';
$has_details = false;
foreach ( $bacs_accounts as $bacs_account ) {
$bacs_account = (object) $bacs_account;
if ( $bacs_account->account_name ) {
$account_html .= '<h3 class="wc-bacs-bank-details-account-name">' . wp_kses_post( wp_unslash( $bacs_account->account_name ) ) . ':</h3>' . PHP_EOL;
}
$account_html .= '<ul class="wc-bacs-bank-details order_details bacs_details">' . PHP_EOL;
// BACS account fields shown on the thanks page and in emails.
$account_fields = apply_filters(
'woocommerce_bacs_account_fields', array(
'bank_name' => array(
'label' => __( 'Bank', 'woocommerce' ),
'value' => $bacs_account->bank_name,
),
'account_number' => array(
'label' => __( 'Account number', 'woocommerce' ),
'value' => $bacs_account->account_number,
),
'sort_code' => array(
'label' => $sortcode,
'value' => $bacs_account->sort_code,
),
'iban' => array(
'label' => __( 'IBAN', 'woocommerce' ),
'value' => $bacs_account->iban,
),
'bic' => array(
'label' => __( 'BIC', 'woocommerce' ),
'value' => $bacs_account->bic,
),
), $order_id
);
foreach ( $account_fields as $field_key => $field ) {
if ( ! empty( $field['value'] ) ) {
$account_html .= '<li class="' . esc_attr( $field_key ) . '">' . wp_kses_post( $field['label'] ) . ': <strong>' . wp_kses_post( wptexturize( $field['value'] ) ) . '</strong></li>' . PHP_EOL;
$has_details = true;
}
}
$account_html .= '</ul>';
}
if ( $has_details ) {
echo '<section class="woocommerce-bacs-bank-details"><h2 class="wc-bacs-bank-details-heading">' . esc_html__( 'Our bank details', 'woocommerce' ) . '</h2>' . wp_kses_post( PHP_EOL . $account_html ) . '</section>';
}
}
}
/**
* Process the payment and return the result.
*
* @param int $order_id Order ID.
* @return array
*/
public function process_payment( $order_id ) {
$order = wc_get_order( $order_id );
if ( $order->get_total() > 0 ) {
// Mark as on-hold (we're awaiting the payment).
$order->update_status( apply_filters( 'woocommerce_bacs_process_payment_order_status', 'on-hold', $order ), __( 'Awaiting BACS payment', 'woocommerce' ) );
} else {
$order->payment_complete();
}
// Reduce stock levels.
wc_reduce_stock_levels( $order_id );
// Remove cart.
WC()->cart->empty_cart();
// Return thankyou redirect.
return array(
'result' => 'success',
'redirect' => $this->get_return_url( $order ),
);
}
/**
* Get country locale if localized.
*
* @return array
*/
public function get_country_locale() {
if ( empty( $this->locale ) ) {
// Locale information to be used - only those that are not 'Sort Code'.
$this->locale = apply_filters(
'woocommerce_get_bacs_locale', array(
'AU' => array(
'sortcode' => array(
'label' => __( 'BSB', 'woocommerce' ),
),
),
'CA' => array(
'sortcode' => array(
'label' => __( 'Bank transit number', 'woocommerce' ),
),
),
'IN' => array(
'sortcode' => array(
'label' => __( 'IFSC', 'woocommerce' ),
),
),
'IT' => array(
'sortcode' => array(
'label' => __( 'Branch sort', 'woocommerce' ),
),
),
'NZ' => array(
'sortcode' => array(
'label' => __( 'Bank code', 'woocommerce' ),
),
),
'SE' => array(
'sortcode' => array(
'label' => __( 'Bank code', 'woocommerce' ),
),
),
'US' => array(
'sortcode' => array(
'label' => __( 'Routing number', 'woocommerce' ),
),
),
'ZA' => array(
'sortcode' => array(
'label' => __( 'Branch code', 'woocommerce' ),
),
),
)
);
}
return $this->locale;
}
}

View File

@@ -0,0 +1,139 @@
<?php
/**
* Class WC_Gateway_Cheque file.
*
* @package WooCommerce\Gateways
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Cheque Payment Gateway.
*
* Provides a Cheque Payment Gateway, mainly for testing purposes.
*
* @class WC_Gateway_Cheque
* @extends WC_Payment_Gateway
* @version 2.1.0
* @package WooCommerce/Classes/Payment
*/
class WC_Gateway_Cheque extends WC_Payment_Gateway {
/**
* Constructor for the gateway.
*/
public function __construct() {
$this->id = 'cheque';
$this->icon = apply_filters( 'woocommerce_cheque_icon', '' );
$this->has_fields = false;
$this->method_title = _x( 'Check payments', 'Check payment method', 'woocommerce' );
$this->method_description = __( 'Take payments in person via checks. This offline gateway can also be useful to test purchases.', 'woocommerce' );
// Load the settings.
$this->init_form_fields();
$this->init_settings();
// Define user set variables.
$this->title = $this->get_option( 'title' );
$this->description = $this->get_option( 'description' );
$this->instructions = $this->get_option( 'instructions' );
// Actions.
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
add_action( 'woocommerce_thankyou_cheque', array( $this, 'thankyou_page' ) );
// Customer Emails.
add_action( 'woocommerce_email_before_order_table', array( $this, 'email_instructions' ), 10, 3 );
}
/**
* Initialise Gateway Settings Form Fields.
*/
public function init_form_fields() {
$this->form_fields = array(
'enabled' => array(
'title' => __( 'Enable/Disable', 'woocommerce' ),
'type' => 'checkbox',
'label' => __( 'Enable check payments', 'woocommerce' ),
'default' => 'no',
),
'title' => array(
'title' => __( 'Title', 'woocommerce' ),
'type' => 'text',
'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ),
'default' => _x( 'Check payments', 'Check payment method', 'woocommerce' ),
'desc_tip' => true,
),
'description' => array(
'title' => __( 'Description', 'woocommerce' ),
'type' => 'textarea',
'description' => __( 'Payment method description that the customer will see on your checkout.', 'woocommerce' ),
'default' => __( 'Please send a check to Store Name, Store Street, Store Town, Store State / County, Store Postcode.', 'woocommerce' ),
'desc_tip' => true,
),
'instructions' => array(
'title' => __( 'Instructions', 'woocommerce' ),
'type' => 'textarea',
'description' => __( 'Instructions that will be added to the thank you page and emails.', 'woocommerce' ),
'default' => '',
'desc_tip' => true,
),
);
}
/**
* Output for the order received page.
*/
public function thankyou_page() {
if ( $this->instructions ) {
echo wp_kses_post( wpautop( wptexturize( $this->instructions ) ) );
}
}
/**
* Add content to the WC emails.
*
* @access public
* @param WC_Order $order Order object.
* @param bool $sent_to_admin Sent to admin.
* @param bool $plain_text Email format: plain text or HTML.
*/
public function email_instructions( $order, $sent_to_admin, $plain_text = false ) {
if ( $this->instructions && ! $sent_to_admin && 'cheque' === $order->get_payment_method() && $order->has_status( 'on-hold' ) ) {
echo wp_kses_post( wpautop( wptexturize( $this->instructions ) ) . PHP_EOL );
}
}
/**
* Process the payment and return the result.
*
* @param int $order_id Order ID.
* @return array
*/
public function process_payment( $order_id ) {
$order = wc_get_order( $order_id );
if ( $order->get_total() > 0 ) {
// Mark as on-hold (we're awaiting the cheque).
$order->update_status( 'on-hold', _x( 'Awaiting check payment', 'Check payment method', 'woocommerce' ) );
} else {
$order->payment_complete();
}
// Reduce stock levels.
wc_reduce_stock_levels( $order_id );
// Remove cart.
WC()->cart->empty_cart();
// Return thankyou redirect.
return array(
'result' => 'success',
'redirect' => $this->get_return_url( $order ),
);
}
}

View File

@@ -0,0 +1,99 @@
<?php
/**
* Class WC_Payment_Gateway_CC file.
*
* @package WooCommerce\Gateways
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Credit Card Payment Gateway
*
* @since 2.6.0
* @package WooCommerce/Classes
*/
class WC_Payment_Gateway_CC extends WC_Payment_Gateway {
/**
* Builds our payment fields area - including tokenization fields for logged
* in users, and the actual payment fields.
*
* @since 2.6.0
*/
public function payment_fields() {
if ( $this->supports( 'tokenization' ) && is_checkout() ) {
$this->tokenization_script();
$this->saved_payment_methods();
$this->form();
$this->save_payment_method_checkbox();
} else {
$this->form();
}
}
/**
* Output field name HTML
*
* Gateways which support tokenization do not require names - we don't want the data to post to the server.
*
* @since 2.6.0
* @param string $name Field name.
* @return string
*/
public function field_name( $name ) {
return $this->supports( 'tokenization' ) ? '' : ' name="' . esc_attr( $this->id . '-' . $name ) . '" ';
}
/**
* Outputs fields for entering credit card information.
*
* @since 2.6.0
*/
public function form() {
wp_enqueue_script( 'wc-credit-card-form' );
$fields = array();
$cvc_field = '<p class="form-row form-row-last">
<label for="' . esc_attr( $this->id ) . '-card-cvc">' . esc_html__( 'Card code', 'woocommerce' ) . '&nbsp;<span class="required">*</span></label>
<input id="' . esc_attr( $this->id ) . '-card-cvc" class="input-text wc-credit-card-form-card-cvc" inputmode="numeric" autocomplete="off" autocorrect="no" autocapitalize="no" spellcheck="no" type="tel" maxlength="4" placeholder="' . esc_attr__( 'CVC', 'woocommerce' ) . '" ' . $this->field_name( 'card-cvc' ) . ' style="width:100px" />
</p>';
$default_fields = array(
'card-number-field' => '<p class="form-row form-row-wide">
<label for="' . esc_attr( $this->id ) . '-card-number">' . esc_html__( 'Card number', 'woocommerce' ) . '&nbsp;<span class="required">*</span></label>
<input id="' . esc_attr( $this->id ) . '-card-number" class="input-text wc-credit-card-form-card-number" inputmode="numeric" autocomplete="cc-number" autocorrect="no" autocapitalize="no" spellcheck="no" type="tel" placeholder="&bull;&bull;&bull;&bull; &bull;&bull;&bull;&bull; &bull;&bull;&bull;&bull; &bull;&bull;&bull;&bull;" ' . $this->field_name( 'card-number' ) . ' />
</p>',
'card-expiry-field' => '<p class="form-row form-row-first">
<label for="' . esc_attr( $this->id ) . '-card-expiry">' . esc_html__( 'Expiry (MM/YY)', 'woocommerce' ) . '&nbsp;<span class="required">*</span></label>
<input id="' . esc_attr( $this->id ) . '-card-expiry" class="input-text wc-credit-card-form-card-expiry" inputmode="numeric" autocomplete="cc-exp" autocorrect="no" autocapitalize="no" spellcheck="no" type="tel" placeholder="' . esc_attr__( 'MM / YY', 'woocommerce' ) . '" ' . $this->field_name( 'card-expiry' ) . ' />
</p>',
);
if ( ! $this->supports( 'credit_card_form_cvc_on_saved_method' ) ) {
$default_fields['card-cvc-field'] = $cvc_field;
}
$fields = wp_parse_args( $fields, apply_filters( 'woocommerce_credit_card_form_fields', $default_fields, $this->id ) );
?>
<fieldset id="wc-<?php echo esc_attr( $this->id ); ?>-cc-form" class='wc-credit-card-form wc-payment-form'>
<?php do_action( 'woocommerce_credit_card_form_start', $this->id ); ?>
<?php
foreach ( $fields as $field ) {
echo $field; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
}
?>
<?php do_action( 'woocommerce_credit_card_form_end', $this->id ); ?>
<div class="clear"></div>
</fieldset>
<?php
if ( $this->supports( 'credit_card_form_cvc_on_saved_method' ) ) {
echo '<fieldset>' . $cvc_field . '</fieldset>'; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
}
}
}

View File

@@ -0,0 +1,71 @@
<?php
/**
* Class WC_Payment_Gateway_eCheck file.
*
* @package WooCommerce\Gateways
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class for eCheck Payment Gateway
*
* @since 2.6.0
* @package WooCommerce/Classes
*/
class WC_Payment_Gateway_ECheck extends WC_Payment_Gateway {
/**
* Builds our payment fields area - including tokenization fields for logged
* in users, and the actual payment fields.
*
* @since 2.6.0
*/
public function payment_fields() {
if ( $this->supports( 'tokenization' ) && is_checkout() ) {
$this->tokenization_script();
$this->saved_payment_methods();
$this->form();
$this->save_payment_method_checkbox();
} else {
$this->form();
}
}
/**
* Outputs fields for entering eCheck information.
*
* @since 2.6.0
*/
public function form() {
$fields = array();
$default_fields = array(
'routing-number' => '<p class="form-row form-row-first">
<label for="' . esc_attr( $this->id ) . '-routing-number">' . esc_html__( 'Routing number', 'woocommerce' ) . '&nbsp;<span class="required">*</span></label>
<input id="' . esc_attr( $this->id ) . '-routing-number" class="input-text wc-echeck-form-routing-number" type="text" maxlength="9" autocomplete="off" placeholder="&bull;&bull;&bull;&bull;&bull;&bull;&bull;&bull;&bull;" name="' . esc_attr( $this->id ) . '-routing-number" />
</p>',
'account-number' => '<p class="form-row form-row-wide">
<label for="' . esc_attr( $this->id ) . '-account-number">' . esc_html__( 'Account number', 'woocommerce' ) . '&nbsp;<span class="required">*</span></label>
<input id="' . esc_attr( $this->id ) . '-account-number" class="input-text wc-echeck-form-account-number" type="text" autocomplete="off" name="' . esc_attr( $this->id ) . '-account-number" maxlength="17" />
</p>',
);
$fields = wp_parse_args( $fields, apply_filters( 'woocommerce_echeck_form_fields', $default_fields, $this->id ) );
?>
<fieldset id="<?php echo esc_attr( $this->id ); ?>-cc-form" class='wc-echeck-form wc-payment-form'>
<?php do_action( 'woocommerce_echeck_form_start', $this->id ); ?>
<?php
foreach ( $fields as $field ) {
echo $field; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
}
?>
<?php do_action( 'woocommerce_echeck_form_end', $this->id ); ?>
<div class="clear"></div>
</fieldset>
<?php
}
}

View File

@@ -0,0 +1,338 @@
<?php
/**
* Class WC_Gateway_COD file.
*
* @package WooCommerce\Gateways
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Cash on Delivery Gateway.
*
* Provides a Cash on Delivery Payment Gateway.
*
* @class WC_Gateway_COD
* @extends WC_Payment_Gateway
* @version 2.1.0
* @package WooCommerce/Classes/Payment
*/
class WC_Gateway_COD extends WC_Payment_Gateway {
/**
* Constructor for the gateway.
*/
public function __construct() {
// Setup general properties.
$this->setup_properties();
// Load the settings.
$this->init_form_fields();
$this->init_settings();
// Get settings.
$this->title = $this->get_option( 'title' );
$this->description = $this->get_option( 'description' );
$this->instructions = $this->get_option( 'instructions' );
$this->enable_for_methods = $this->get_option( 'enable_for_methods', array() );
$this->enable_for_virtual = $this->get_option( 'enable_for_virtual', 'yes' ) === 'yes';
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
add_action( 'woocommerce_thankyou_' . $this->id, array( $this, 'thankyou_page' ) );
add_filter( 'woocommerce_payment_complete_order_status', array( $this, 'change_payment_complete_order_status' ), 10, 3 );
// Customer Emails.
add_action( 'woocommerce_email_before_order_table', array( $this, 'email_instructions' ), 10, 3 );
}
/**
* Setup general properties for the gateway.
*/
protected function setup_properties() {
$this->id = 'cod';
$this->icon = apply_filters( 'woocommerce_cod_icon', '' );
$this->method_title = __( 'Cash on delivery', 'woocommerce' );
$this->method_description = __( 'Have your customers pay with cash (or by other means) upon delivery.', 'woocommerce' );
$this->has_fields = false;
}
/**
* Initialise Gateway Settings Form Fields.
*/
public function init_form_fields() {
$options = array();
$data_store = WC_Data_Store::load( 'shipping-zone' );
$raw_zones = $data_store->get_zones();
foreach ( $raw_zones as $raw_zone ) {
$zones[] = new WC_Shipping_Zone( $raw_zone );
}
$zones[] = new WC_Shipping_Zone( 0 );
foreach ( WC()->shipping()->load_shipping_methods() as $method ) {
$options[ $method->get_method_title() ] = array();
// Translators: %1$s shipping method name.
$options[ $method->get_method_title() ][ $method->id ] = sprintf( __( 'Any &quot;%1$s&quot; method', 'woocommerce' ), $method->get_method_title() );
foreach ( $zones as $zone ) {
$shipping_method_instances = $zone->get_shipping_methods();
foreach ( $shipping_method_instances as $shipping_method_instance_id => $shipping_method_instance ) {
if ( $shipping_method_instance->id !== $method->id ) {
continue;
}
$option_id = $shipping_method_instance->get_rate_id();
// Translators: %1$s shipping method title, %2$s shipping method id.
$option_instance_title = sprintf( __( '%1$s (#%2$s)', 'woocommerce' ), $shipping_method_instance->get_title(), $shipping_method_instance_id );
// Translators: %1$s zone name, %2$s shipping method instance name.
$option_title = sprintf( __( '%1$s &ndash; %2$s', 'woocommerce' ), $zone->get_id() ? $zone->get_zone_name() : __( 'Other locations', 'woocommerce' ), $option_instance_title );
$options[ $method->get_method_title() ][ $option_id ] = $option_title;
}
}
}
$this->form_fields = array(
'enabled' => array(
'title' => __( 'Enable/Disable', 'woocommerce' ),
'label' => __( 'Enable cash on delivery', 'woocommerce' ),
'type' => 'checkbox',
'description' => '',
'default' => 'no',
),
'title' => array(
'title' => __( 'Title', 'woocommerce' ),
'type' => 'text',
'description' => __( 'Payment method description that the customer will see on your checkout.', 'woocommerce' ),
'default' => __( 'Cash on delivery', 'woocommerce' ),
'desc_tip' => true,
),
'description' => array(
'title' => __( 'Description', 'woocommerce' ),
'type' => 'textarea',
'description' => __( 'Payment method description that the customer will see on your website.', 'woocommerce' ),
'default' => __( 'Pay with cash upon delivery.', 'woocommerce' ),
'desc_tip' => true,
),
'instructions' => array(
'title' => __( 'Instructions', 'woocommerce' ),
'type' => 'textarea',
'description' => __( 'Instructions that will be added to the thank you page.', 'woocommerce' ),
'default' => __( 'Pay with cash upon delivery.', 'woocommerce' ),
'desc_tip' => true,
),
'enable_for_methods' => array(
'title' => __( 'Enable for shipping methods', 'woocommerce' ),
'type' => 'multiselect',
'class' => 'wc-enhanced-select',
'css' => 'width: 400px;',
'default' => '',
'description' => __( 'If COD is only available for certain methods, set it up here. Leave blank to enable for all methods.', 'woocommerce' ),
'options' => $options,
'desc_tip' => true,
'custom_attributes' => array(
'data-placeholder' => __( 'Select shipping methods', 'woocommerce' ),
),
),
'enable_for_virtual' => array(
'title' => __( 'Accept for virtual orders', 'woocommerce' ),
'label' => __( 'Accept COD if the order is virtual', 'woocommerce' ),
'type' => 'checkbox',
'default' => 'yes',
),
);
}
/**
* Check If The Gateway Is Available For Use.
*
* @return bool
*/
public function is_available() {
$order = null;
$needs_shipping = false;
// Test if shipping is needed first.
if ( WC()->cart && WC()->cart->needs_shipping() ) {
$needs_shipping = true;
} elseif ( is_page( wc_get_page_id( 'checkout' ) ) && 0 < get_query_var( 'order-pay' ) ) {
$order_id = absint( get_query_var( 'order-pay' ) );
$order = wc_get_order( $order_id );
// Test if order needs shipping.
if ( 0 < count( $order->get_items() ) ) {
foreach ( $order->get_items() as $item ) {
$_product = $item->get_product();
if ( $_product && $_product->needs_shipping() ) {
$needs_shipping = true;
break;
}
}
}
} elseif ( WC()->cart && WC()->cart->needs_shipping() ) {
$needs_shipping = true;
}
$needs_shipping = apply_filters( 'woocommerce_cart_needs_shipping', $needs_shipping );
// Virtual order, with virtual disabled.
if ( ! $this->enable_for_virtual && ! $needs_shipping ) {
return false;
}
// Only apply if all packages are being shipped via chosen method, or order is virtual.
if ( ! empty( $this->enable_for_methods ) && $needs_shipping ) {
$canonical_rate_ids = array();
$order_shipping_items = is_object( $order ) ? $order->get_shipping_methods() : false;
$chosen_shipping_methods_session = WC()->session->get( 'chosen_shipping_methods' );
if ( $order_shipping_items ) {
$canonical_rate_ids = $this->get_canonical_order_shipping_item_rate_ids( $order_shipping_items );
} else {
$canonical_rate_ids = $this->get_canonical_package_rate_ids( $chosen_shipping_methods_session );
}
if ( ! count( $this->get_matching_rates( $canonical_rate_ids ) ) ) {
return false;
}
}
return parent::is_available();
}
/**
* Converts the chosen rate IDs generated by Shipping Methods to a canonical 'method_id:instance_id' format.
*
* @since 3.4.0
*
* @param array $order_shipping_items Array of WC_Order_Item_Shipping objects.
* @return array $canonical_rate_ids Rate IDs in a canonical format.
*/
private function get_canonical_order_shipping_item_rate_ids( $order_shipping_items ) {
$canonical_rate_ids = array();
foreach ( $order_shipping_items as $order_shipping_item ) {
$canonical_rate_ids[] = $order_shipping_item->get_method_id() . ':' . $order_shipping_item->get_instance_id();
}
return $canonical_rate_ids;
}
/**
* Converts the chosen rate IDs generated by Shipping Methods to a canonical 'method_id:instance_id' format.
*
* @since 3.4.0
*
* @param array $chosen_package_rate_ids Rate IDs as generated by shipping methods. Can be anything if a shipping method doesn't honor WC conventions.
* @return array $canonical_rate_ids Rate IDs in a canonical format.
*/
private function get_canonical_package_rate_ids( $chosen_package_rate_ids ) {
$shipping_packages = WC()->shipping->get_packages();
$canonical_rate_ids = array();
if ( ! empty( $chosen_package_rate_ids ) && is_array( $chosen_package_rate_ids ) ) {
foreach ( $chosen_package_rate_ids as $package_key => $chosen_package_rate_id ) {
if ( ! empty( $shipping_packages[ $package_key ]['rates'][ $chosen_package_rate_id ] ) ) {
$chosen_rate = $shipping_packages[ $package_key ]['rates'][ $chosen_package_rate_id ];
$canonical_rate_ids[] = $chosen_rate->get_method_id() . ':' . $chosen_rate->get_instance_id();
}
}
}
return $canonical_rate_ids;
}
/**
* Indicates whether a rate exists in an array of canonically-formatted rate IDs that activates this gateway.
*
* @since 3.4.0
*
* @param array $rate_ids Rate ids to check.
* @return boolean
*/
private function get_matching_rates( $rate_ids ) {
// First, match entries in 'method_id:instance_id' format. Then, match entries in 'method_id' format by stripping off the instance ID from the candidates.
return array_unique( array_merge( array_intersect( $this->enable_for_methods, $rate_ids ), array_intersect( $this->enable_for_methods, array_unique( array_map( 'wc_get_string_before_colon', $rate_ids ) ) ) ) );
}
/**
* Process the payment and return the result.
*
* @param int $order_id Order ID.
* @return array
*/
public function process_payment( $order_id ) {
$order = wc_get_order( $order_id );
if ( $order->get_total() > 0 ) {
// Mark as processing or on-hold (payment won't be taken until delivery).
$order->update_status( apply_filters( 'woocommerce_cod_process_payment_order_status', $order->has_downloadable_item() ? 'on-hold' : 'processing', $order ), __( 'Payment to be made upon delivery.', 'woocommerce' ) );
} else {
$order->payment_complete();
}
// Reduce stock levels.
wc_reduce_stock_levels( $order_id );
// Remove cart.
WC()->cart->empty_cart();
// Return thankyou redirect.
return array(
'result' => 'success',
'redirect' => $this->get_return_url( $order ),
);
}
/**
* Output for the order received page.
*/
public function thankyou_page() {
if ( $this->instructions ) {
echo wp_kses_post( wpautop( wptexturize( $this->instructions ) ) );
}
}
/**
* Change payment complete order status to completed for COD orders.
*
* @since 3.1.0
* @param string $status Current order status.
* @param int $order_id Order ID.
* @param WC_Order|false $order Order object.
* @return string
*/
public function change_payment_complete_order_status( $status, $order_id = 0, $order = false ) {
if ( $order && 'cod' === $order->get_payment_method() ) {
$status = 'completed';
}
return $status;
}
/**
* Add content to the WC emails.
*
* @access public
* @param WC_Order $order Order object.
* @param bool $sent_to_admin Sent to admin.
* @param bool $plain_text Email format: plain text or HTML.
*/
public function email_instructions( $order, $sent_to_admin, $plain_text = false ) {
if ( $this->instructions && ! $sent_to_admin && $this->id === $order->get_payment_method() ) {
echo wp_kses_post( wpautop( wptexturize( $this->instructions ) ) . PHP_EOL );
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -0,0 +1,46 @@
jQuery( function( $ ) {
'use strict';
/**
* Object to handle PayPal admin functions.
*/
var wc_paypal_admin = {
isTestMode: function() {
return $( '#woocommerce_paypal_testmode' ).is( ':checked' );
},
/**
* Initialize.
*/
init: function() {
$( document.body ).on( 'change', '#woocommerce_paypal_testmode', function() {
var test_api_username = $( '#woocommerce_paypal_sandbox_api_username' ).parents( 'tr' ).eq( 0 ),
test_api_password = $( '#woocommerce_paypal_sandbox_api_password' ).parents( 'tr' ).eq( 0 ),
test_api_signature = $( '#woocommerce_paypal_sandbox_api_signature' ).parents( 'tr' ).eq( 0 ),
live_api_username = $( '#woocommerce_paypal_api_username' ).parents( 'tr' ).eq( 0 ),
live_api_password = $( '#woocommerce_paypal_api_password' ).parents( 'tr' ).eq( 0 ),
live_api_signature = $( '#woocommerce_paypal_api_signature' ).parents( 'tr' ).eq( 0 );
if ( $( this ).is( ':checked' ) ) {
test_api_username.show();
test_api_password.show();
test_api_signature.show();
live_api_username.hide();
live_api_password.hide();
live_api_signature.hide();
} else {
test_api_username.hide();
test_api_password.hide();
test_api_signature.hide();
live_api_username.show();
live_api_password.show();
live_api_signature.show();
}
} );
$( '#woocommerce_paypal_testmode' ).change();
}
};
wc_paypal_admin.init();
});

View File

@@ -0,0 +1 @@
jQuery(function($){'use strict';var wc_paypal_admin={isTestMode:function(){return $('#woocommerce_paypal_testmode').is(':checked')},init:function(){$(document.body).on('change','#woocommerce_paypal_testmode',function(){var test_api_username=$('#woocommerce_paypal_sandbox_api_username').parents('tr').eq(0),test_api_password=$('#woocommerce_paypal_sandbox_api_password').parents('tr').eq(0),test_api_signature=$('#woocommerce_paypal_sandbox_api_signature').parents('tr').eq(0),live_api_username=$('#woocommerce_paypal_api_username').parents('tr').eq(0),live_api_password=$('#woocommerce_paypal_api_password').parents('tr').eq(0),live_api_signature=$('#woocommerce_paypal_api_signature').parents('tr').eq(0);if($(this).is(':checked')){test_api_username.show();test_api_password.show();test_api_signature.show();live_api_username.hide();live_api_password.hide();live_api_signature.hide()}else{test_api_username.hide();test_api_password.hide();test_api_signature.hide();live_api_username.show();live_api_password.show();live_api_signature.show()}});$('#woocommerce_paypal_testmode').change()}};wc_paypal_admin.init()})

View File

@@ -0,0 +1,448 @@
<?php
/**
* PayPal Standard Payment Gateway.
*
* Provides a PayPal Standard Payment Gateway.
*
* @class WC_Gateway_Paypal
* @extends WC_Payment_Gateway
* @version 2.3.0
* @package WooCommerce/Classes/Payment
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* WC_Gateway_Paypal Class.
*/
class WC_Gateway_Paypal extends WC_Payment_Gateway {
/**
* Whether or not logging is enabled
*
* @var bool
*/
public static $log_enabled = false;
/**
* Logger instance
*
* @var WC_Logger
*/
public static $log = false;
/**
* Constructor for the gateway.
*/
public function __construct() {
$this->id = 'paypal';
$this->has_fields = false;
$this->order_button_text = __( 'Proceed to PayPal', 'woocommerce' );
$this->method_title = __( 'PayPal', 'woocommerce' );
/* translators: %s: Link to WC system status page */
$this->method_description = __( 'PayPal Standard redirects customers to PayPal to enter their payment information.', 'woocommerce' );
$this->supports = array(
'products',
'refunds',
);
// Load the settings.
$this->init_form_fields();
$this->init_settings();
// Define user set variables.
$this->title = $this->get_option( 'title' );
$this->description = $this->get_option( 'description' );
$this->testmode = 'yes' === $this->get_option( 'testmode', 'no' );
$this->debug = 'yes' === $this->get_option( 'debug', 'no' );
$this->email = $this->get_option( 'email' );
$this->receiver_email = $this->get_option( 'receiver_email', $this->email );
$this->identity_token = $this->get_option( 'identity_token' );
self::$log_enabled = $this->debug;
if ( $this->testmode ) {
/* translators: %s: Link to PayPal sandbox testing guide page */
$this->description .= ' ' . sprintf( __( 'SANDBOX ENABLED. You can use sandbox testing accounts only. See the <a href="%s">PayPal Sandbox Testing Guide</a> for more details.', 'woocommerce' ), 'https://developer.paypal.com/docs/classic/lifecycle/ug_sandbox/' );
$this->description = trim( $this->description );
}
add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ) );
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
add_action( 'woocommerce_order_status_on-hold_to_processing', array( $this, 'capture_payment' ) );
add_action( 'woocommerce_order_status_on-hold_to_completed', array( $this, 'capture_payment' ) );
if ( ! $this->is_valid_for_use() ) {
$this->enabled = 'no';
} else {
include_once dirname( __FILE__ ) . '/includes/class-wc-gateway-paypal-ipn-handler.php';
new WC_Gateway_Paypal_IPN_Handler( $this->testmode, $this->receiver_email );
if ( $this->identity_token ) {
include_once dirname( __FILE__ ) . '/includes/class-wc-gateway-paypal-pdt-handler.php';
new WC_Gateway_Paypal_PDT_Handler( $this->testmode, $this->identity_token );
}
}
}
/**
* Return whether or not this gateway still requires setup to function.
*
* When this gateway is toggled on via AJAX, if this returns true a
* redirect will occur to the settings page instead.
*
* @since 3.4.0
* @return bool
*/
public function needs_setup() {
return ! is_email( $this->email );
}
/**
* Logging method.
*
* @param string $message Log message.
* @param string $level Optional. Default 'info'. Possible values:
* emergency|alert|critical|error|warning|notice|info|debug.
*/
public static function log( $message, $level = 'info' ) {
if ( self::$log_enabled ) {
if ( empty( self::$log ) ) {
self::$log = wc_get_logger();
}
self::$log->log( $level, $message, array( 'source' => 'paypal' ) );
}
}
/**
* Processes and saves options.
* If there is an error thrown, will continue to save and validate fields, but will leave the erroring field out.
*
* @return bool was anything saved?
*/
public function process_admin_options() {
$saved = parent::process_admin_options();
// Maybe clear logs.
if ( 'yes' !== $this->get_option( 'debug', 'no' ) ) {
if ( empty( self::$log ) ) {
self::$log = wc_get_logger();
}
self::$log->clear( 'paypal' );
}
return $saved;
}
/**
* Get gateway icon.
*
* @return string
*/
public function get_icon() {
$icon_html = '';
$icon = (array) $this->get_icon_image( WC()->countries->get_base_country() );
foreach ( $icon as $i ) {
$icon_html .= '<img src="' . esc_attr( $i ) . '" alt="' . esc_attr__( 'PayPal acceptance mark', 'woocommerce' ) . '" />';
}
$icon_html .= sprintf( '<a href="%1$s" class="about_paypal" onclick="javascript:window.open(\'%1$s\',\'WIPaypal\',\'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, width=1060, height=700\'); return false;">' . esc_attr__( 'What is PayPal?', 'woocommerce' ) . '</a>', esc_url( $this->get_icon_url( WC()->countries->get_base_country() ) ) );
return apply_filters( 'woocommerce_gateway_icon', $icon_html, $this->id );
}
/**
* Get the link for an icon based on country.
*
* @param string $country Country two letter code.
* @return string
*/
protected function get_icon_url( $country ) {
$url = 'https://www.paypal.com/' . strtolower( $country );
$home_counties = array( 'BE', 'CZ', 'DK', 'HU', 'IT', 'JP', 'NL', 'NO', 'ES', 'SE', 'TR', 'IN' );
$countries = array( 'DZ', 'AU', 'BH', 'BQ', 'BW', 'CA', 'CN', 'CW', 'FI', 'FR', 'DE', 'GR', 'HK', 'ID', 'JO', 'KE', 'KW', 'LU', 'MY', 'MA', 'OM', 'PH', 'PL', 'PT', 'QA', 'IE', 'RU', 'BL', 'SX', 'MF', 'SA', 'SG', 'SK', 'KR', 'SS', 'TW', 'TH', 'AE', 'GB', 'US', 'VN' );
if ( in_array( $country, $home_counties, true ) ) {
return $url . '/webapps/mpp/home';
} elseif ( in_array( $country, $countries, true ) ) {
return $url . '/webapps/mpp/paypal-popup';
} else {
return $url . '/cgi-bin/webscr?cmd=xpt/Marketing/general/WIPaypal-outside';
}
}
/**
* Get PayPal images for a country.
*
* @param string $country Country code.
* @return array of image URLs
*/
protected function get_icon_image( $country ) {
switch ( $country ) {
case 'US':
case 'NZ':
case 'CZ':
case 'HU':
case 'MY':
$icon = 'https://www.paypalobjects.com/webstatic/mktg/logo/AM_mc_vs_dc_ae.jpg';
break;
case 'TR':
$icon = 'https://www.paypalobjects.com/webstatic/mktg/logo-center/logo_paypal_odeme_secenekleri.jpg';
break;
case 'GB':
$icon = 'https://www.paypalobjects.com/webstatic/mktg/Logo/AM_mc_vs_ms_ae_UK.png';
break;
case 'MX':
$icon = array(
'https://www.paypal.com/es_XC/Marketing/i/banner/paypal_visa_mastercard_amex.png',
'https://www.paypal.com/es_XC/Marketing/i/banner/paypal_debit_card_275x60.gif',
);
break;
case 'FR':
$icon = 'https://www.paypalobjects.com/webstatic/mktg/logo-center/logo_paypal_moyens_paiement_fr.jpg';
break;
case 'AU':
$icon = 'https://www.paypalobjects.com/webstatic/en_AU/mktg/logo/Solutions-graphics-1-184x80.jpg';
break;
case 'DK':
$icon = 'https://www.paypalobjects.com/webstatic/mktg/logo-center/logo_PayPal_betalingsmuligheder_dk.jpg';
break;
case 'RU':
$icon = 'https://www.paypalobjects.com/webstatic/ru_RU/mktg/business/pages/logo-center/AM_mc_vs_dc_ae.jpg';
break;
case 'NO':
$icon = 'https://www.paypalobjects.com/webstatic/mktg/logo-center/banner_pl_just_pp_319x110.jpg';
break;
case 'CA':
$icon = 'https://www.paypalobjects.com/webstatic/en_CA/mktg/logo-image/AM_mc_vs_dc_ae.jpg';
break;
case 'HK':
$icon = 'https://www.paypalobjects.com/webstatic/en_HK/mktg/logo/AM_mc_vs_dc_ae.jpg';
break;
case 'SG':
$icon = 'https://www.paypalobjects.com/webstatic/en_SG/mktg/Logos/AM_mc_vs_dc_ae.jpg';
break;
case 'TW':
$icon = 'https://www.paypalobjects.com/webstatic/en_TW/mktg/logos/AM_mc_vs_dc_ae.jpg';
break;
case 'TH':
$icon = 'https://www.paypalobjects.com/webstatic/en_TH/mktg/Logos/AM_mc_vs_dc_ae.jpg';
break;
case 'JP':
$icon = 'https://www.paypal.com/ja_JP/JP/i/bnr/horizontal_solution_4_jcb.gif';
break;
case 'IN':
$icon = 'https://www.paypalobjects.com/webstatic/mktg/logo/AM_mc_vs_dc_ae.jpg';
break;
default:
$icon = WC_HTTPS::force_https_url( WC()->plugin_url() . '/includes/gateways/paypal/assets/images/paypal.png' );
break;
}
return apply_filters( 'woocommerce_paypal_icon', $icon );
}
/**
* Check if this gateway is enabled and available in the user's country.
*
* @return bool
*/
public function is_valid_for_use() {
return in_array(
get_woocommerce_currency(),
apply_filters(
'woocommerce_paypal_supported_currencies',
array( 'AUD', 'BRL', 'CAD', 'MXN', 'NZD', 'HKD', 'SGD', 'USD', 'EUR', 'JPY', 'TRY', 'NOK', 'CZK', 'DKK', 'HUF', 'ILS', 'MYR', 'PHP', 'PLN', 'SEK', 'CHF', 'TWD', 'THB', 'GBP', 'RMB', 'RUB', 'INR' )
),
true
);
}
/**
* Admin Panel Options.
* - Options for bits like 'title' and availability on a country-by-country basis.
*
* @since 1.0.0
*/
public function admin_options() {
if ( $this->is_valid_for_use() ) {
parent::admin_options();
} else {
?>
<div class="inline error">
<p>
<strong><?php esc_html_e( 'Gateway disabled', 'woocommerce' ); ?></strong>: <?php esc_html_e( 'PayPal does not support your store currency.', 'woocommerce' ); ?>
</p>
</div>
<?php
}
}
/**
* Initialise Gateway Settings Form Fields.
*/
public function init_form_fields() {
$this->form_fields = include 'includes/settings-paypal.php';
}
/**
* Get the transaction URL.
*
* @param WC_Order $order Order object.
* @return string
*/
public function get_transaction_url( $order ) {
if ( $this->testmode ) {
$this->view_transaction_url = 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_view-a-trans&id=%s';
} else {
$this->view_transaction_url = 'https://www.paypal.com/cgi-bin/webscr?cmd=_view-a-trans&id=%s';
}
return parent::get_transaction_url( $order );
}
/**
* Process the payment and return the result.
*
* @param int $order_id Order ID.
* @return array
*/
public function process_payment( $order_id ) {
include_once dirname( __FILE__ ) . '/includes/class-wc-gateway-paypal-request.php';
$order = wc_get_order( $order_id );
$paypal_request = new WC_Gateway_Paypal_Request( $this );
return array(
'result' => 'success',
'redirect' => $paypal_request->get_request_url( $order, $this->testmode ),
);
}
/**
* Can the order be refunded via PayPal?
*
* @param WC_Order $order Order object.
* @return bool
*/
public function can_refund_order( $order ) {
$has_api_creds = false;
if ( $this->testmode ) {
$has_api_creds = $this->get_option( 'sandbox_api_username' ) && $this->get_option( 'sandbox_api_password' ) && $this->get_option( 'sandbox_api_signature' );
} else {
$has_api_creds = $this->get_option( 'api_username' ) && $this->get_option( 'api_password' ) && $this->get_option( 'api_signature' );
}
return $order && $order->get_transaction_id() && $has_api_creds;
}
/**
* Init the API class and set the username/password etc.
*/
protected function init_api() {
include_once dirname( __FILE__ ) . '/includes/class-wc-gateway-paypal-api-handler.php';
WC_Gateway_Paypal_API_Handler::$api_username = $this->testmode ? $this->get_option( 'sandbox_api_username' ) : $this->get_option( 'api_username' );
WC_Gateway_Paypal_API_Handler::$api_password = $this->testmode ? $this->get_option( 'sandbox_api_password' ) : $this->get_option( 'api_password' );
WC_Gateway_Paypal_API_Handler::$api_signature = $this->testmode ? $this->get_option( 'sandbox_api_signature' ) : $this->get_option( 'api_signature' );
WC_Gateway_Paypal_API_Handler::$sandbox = $this->testmode;
}
/**
* Process a refund if supported.
*
* @param int $order_id Order ID.
* @param float $amount Refund amount.
* @param string $reason Refund reason.
* @return bool|WP_Error
*/
public function process_refund( $order_id, $amount = null, $reason = '' ) {
$order = wc_get_order( $order_id );
if ( ! $this->can_refund_order( $order ) ) {
return new WP_Error( 'error', __( 'Refund failed.', 'woocommerce' ) );
}
$this->init_api();
$result = WC_Gateway_Paypal_API_Handler::refund_transaction( $order, $amount, $reason );
if ( is_wp_error( $result ) ) {
$this->log( 'Refund Failed: ' . $result->get_error_message(), 'error' );
return new WP_Error( 'error', $result->get_error_message() );
}
$this->log( 'Refund Result: ' . wc_print_r( $result, true ) );
switch ( strtolower( $result->ACK ) ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
case 'success':
case 'successwithwarning':
$order->add_order_note(
/* translators: 1: Refund amount, 2: Refund ID */
sprintf( __( 'Refunded %1$s - Refund ID: %2$s', 'woocommerce' ), $result->GROSSREFUNDAMT, $result->REFUNDTRANSACTIONID ) // phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
);
return true;
}
return isset( $result->L_LONGMESSAGE0 ) ? new WP_Error( 'error', $result->L_LONGMESSAGE0 ) : false; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
}
/**
* Capture payment when the order is changed from on-hold to complete or processing
*
* @param int $order_id Order ID.
*/
public function capture_payment( $order_id ) {
$order = wc_get_order( $order_id );
if ( 'paypal' === $order->get_payment_method() && 'pending' === get_post_meta( $order->get_id(), '_paypal_status', true ) && $order->get_transaction_id() ) {
$this->init_api();
$result = WC_Gateway_Paypal_API_Handler::do_capture( $order );
if ( is_wp_error( $result ) ) {
$this->log( 'Capture Failed: ' . $result->get_error_message(), 'error' );
/* translators: %s: Paypal gateway error message */
$order->add_order_note( sprintf( __( 'Payment could not captured: %s', 'woocommerce' ), $result->get_error_message() ) );
return;
}
$this->log( 'Capture Result: ' . wc_print_r( $result, true ) );
// phpcs:disable WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
if ( ! empty( $result->PAYMENTSTATUS ) ) {
switch ( $result->PAYMENTSTATUS ) {
case 'Completed':
/* translators: 1: Amount, 2: Authorization ID, 3: Transaction ID */
$order->add_order_note( sprintf( __( 'Payment of %1$s was captured - Auth ID: %2$s, Transaction ID: %3$s', 'woocommerce' ), $result->AMT, $result->AUTHORIZATIONID, $result->TRANSACTIONID ) );
update_post_meta( $order->get_id(), '_paypal_status', $result->PAYMENTSTATUS );
update_post_meta( $order->get_id(), '_transaction_id', $result->TRANSACTIONID );
break;
default:
/* translators: 1: Authorization ID, 2: Payment status */
$order->add_order_note( sprintf( __( 'Payment could not captured - Auth ID: %1$s, Status: %2$s', 'woocommerce' ), $result->AUTHORIZATIONID, $result->PAYMENTSTATUS ) );
break;
}
}
// phpcs:enable
}
}
/**
* Load admin scripts.
*
* @since 3.3.0
*/
public function admin_scripts() {
$screen = get_current_screen();
$screen_id = $screen ? $screen->id : '';
if ( 'woocommerce_page_wc-settings' !== $screen_id ) {
return;
}
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
wp_enqueue_script( 'woocommerce_paypal_admin', WC()->plugin_url() . '/includes/gateways/paypal/assets/js/paypal-admin' . $suffix . '.js', array(), WC_VERSION, true );
}
}

View File

@@ -0,0 +1,202 @@
<?php
/**
* Class WC_Gateway_Paypal_API_Handler file.
*
* @package WooCommerce\Gateways
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Handles Refunds and other API requests such as capture.
*
* @since 3.0.0
*/
class WC_Gateway_Paypal_API_Handler {
/**
* API Username
*
* @var string
*/
public static $api_username;
/**
* API Password
*
* @var string
*/
public static $api_password;
/**
* API Signature
*
* @var string
*/
public static $api_signature;
/**
* Sandbox
*
* @var bool
*/
public static $sandbox = false;
/**
* Get capture request args.
* See https://developer.paypal.com/docs/classic/api/merchant/DoCapture_API_Operation_NVP/.
*
* @param WC_Order $order Order object.
* @param float $amount Amount.
* @return array
*/
public static function get_capture_request( $order, $amount = null ) {
$request = array(
'VERSION' => '84.0',
'SIGNATURE' => self::$api_signature,
'USER' => self::$api_username,
'PWD' => self::$api_password,
'METHOD' => 'DoCapture',
'AUTHORIZATIONID' => $order->get_transaction_id(),
'AMT' => number_format( is_null( $amount ) ? $order->get_total() : $amount, 2, '.', '' ),
'CURRENCYCODE' => $order->get_currency(),
'COMPLETETYPE' => 'Complete',
);
return apply_filters( 'woocommerce_paypal_capture_request', $request, $order, $amount );
}
/**
* Get refund request args.
*
* @param WC_Order $order Order object.
* @param float $amount Refund amount.
* @param string $reason Refund reason.
* @return array
*/
public static function get_refund_request( $order, $amount = null, $reason = '' ) {
$request = array(
'VERSION' => '84.0',
'SIGNATURE' => self::$api_signature,
'USER' => self::$api_username,
'PWD' => self::$api_password,
'METHOD' => 'RefundTransaction',
'TRANSACTIONID' => $order->get_transaction_id(),
'NOTE' => html_entity_decode( wc_trim_string( $reason, 255 ), ENT_NOQUOTES, 'UTF-8' ),
'REFUNDTYPE' => 'Full',
);
if ( ! is_null( $amount ) ) {
$request['AMT'] = number_format( $amount, 2, '.', '' );
$request['CURRENCYCODE'] = $order->get_currency();
$request['REFUNDTYPE'] = 'Partial';
}
return apply_filters( 'woocommerce_paypal_refund_request', $request, $order, $amount, $reason );
}
/**
* Capture an authorization.
*
* @param WC_Order $order Order object.
* @param float $amount Amount.
* @return object Either an object of name value pairs for a success, or a WP_ERROR object.
*/
public static function do_capture( $order, $amount = null ) {
$raw_response = wp_safe_remote_post(
self::$sandbox ? 'https://api-3t.sandbox.paypal.com/nvp' : 'https://api-3t.paypal.com/nvp',
array(
'method' => 'POST',
'body' => self::get_capture_request( $order, $amount ),
'timeout' => 70,
'user-agent' => 'WooCommerce/' . WC()->version,
'httpversion' => '1.1',
)
);
WC_Gateway_Paypal::log( 'DoCapture Response: ' . wc_print_r( $raw_response, true ) );
if ( empty( $raw_response['body'] ) ) {
return new WP_Error( 'paypal-api', 'Empty Response' );
} elseif ( is_wp_error( $raw_response ) ) {
return $raw_response;
}
parse_str( $raw_response['body'], $response );
return (object) $response;
}
/**
* Refund an order via PayPal.
*
* @param WC_Order $order Order object.
* @param float $amount Refund amount.
* @param string $reason Refund reason.
* @return object Either an object of name value pairs for a success, or a WP_ERROR object.
*/
public static function refund_transaction( $order, $amount = null, $reason = '' ) {
$raw_response = wp_safe_remote_post(
self::$sandbox ? 'https://api-3t.sandbox.paypal.com/nvp' : 'https://api-3t.paypal.com/nvp',
array(
'method' => 'POST',
'body' => self::get_refund_request( $order, $amount, $reason ),
'timeout' => 70,
'user-agent' => 'WooCommerce/' . WC()->version,
'httpversion' => '1.1',
)
);
WC_Gateway_Paypal::log( 'Refund Response: ' . wc_print_r( $raw_response, true ) );
if ( empty( $raw_response['body'] ) ) {
return new WP_Error( 'paypal-api', 'Empty Response' );
} elseif ( is_wp_error( $raw_response ) ) {
return $raw_response;
}
parse_str( $raw_response['body'], $response );
return (object) $response;
}
}
/**
* Here for backwards compatibility.
*
* @since 3.0.0
*/
class WC_Gateway_Paypal_Refund extends WC_Gateway_Paypal_API_Handler {
/**
* Get refund request args. Proxy to WC_Gateway_Paypal_API_Handler::get_refund_request().
*
* @param WC_Order $order Order object.
* @param float $amount Refund amount.
* @param string $reason Refund reason.
*
* @return array
*/
public static function get_request( $order, $amount = null, $reason = '' ) {
return self::get_refund_request( $order, $amount, $reason );
}
/**
* Process an order refund.
*
* @param WC_Order $order Order object.
* @param float $amount Refund amount.
* @param string $reason Refund reason.
* @param bool $sandbox Whether to use sandbox mode or not.
* @return object Either an object of name value pairs for a success, or a WP_ERROR object.
*/
public static function refund_order( $order, $amount = null, $reason = '', $sandbox = false ) {
if ( $sandbox ) {
self::$sandbox = $sandbox;
}
$result = self::refund_transaction( $order, $amount, $reason );
if ( is_wp_error( $result ) ) {
return $result;
} else {
return (array) $result;
}
}
}

View File

@@ -0,0 +1,378 @@
<?php
/**
* Handles responses from PayPal IPN.
*
* @package WooCommerce/PayPal
* @version 3.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
require_once dirname( __FILE__ ) . '/class-wc-gateway-paypal-response.php';
/**
* WC_Gateway_Paypal_IPN_Handler class.
*/
class WC_Gateway_Paypal_IPN_Handler extends WC_Gateway_Paypal_Response {
/**
* Receiver email address to validate.
*
* @var string Receiver email address.
*/
protected $receiver_email;
/**
* Constructor.
*
* @param bool $sandbox Use sandbox or not.
* @param string $receiver_email Email to receive IPN from.
*/
public function __construct( $sandbox = false, $receiver_email = '' ) {
add_action( 'woocommerce_api_wc_gateway_paypal', array( $this, 'check_response' ) );
add_action( 'valid-paypal-standard-ipn-request', array( $this, 'valid_response' ) );
$this->receiver_email = $receiver_email;
$this->sandbox = $sandbox;
}
/**
* Check for PayPal IPN Response.
*/
public function check_response() {
if ( ! empty( $_POST ) && $this->validate_ipn() ) { // WPCS: CSRF ok.
$posted = wp_unslash( $_POST ); // WPCS: CSRF ok, input var ok.
// @codingStandardsIgnoreStart
do_action( 'valid-paypal-standard-ipn-request', $posted );
// @codingStandardsIgnoreEnd
exit;
}
wp_die( 'PayPal IPN Request Failure', 'PayPal IPN', array( 'response' => 500 ) );
}
/**
* There was a valid response.
*
* @param array $posted Post data after wp_unslash.
*/
public function valid_response( $posted ) {
$order = ! empty( $posted['custom'] ) ? $this->get_paypal_order( $posted['custom'] ) : false;
if ( $order ) {
// Lowercase returned variables.
$posted['payment_status'] = strtolower( $posted['payment_status'] );
WC_Gateway_Paypal::log( 'Found order #' . $order->get_id() );
WC_Gateway_Paypal::log( 'Payment status: ' . $posted['payment_status'] );
if ( method_exists( $this, 'payment_status_' . $posted['payment_status'] ) ) {
call_user_func( array( $this, 'payment_status_' . $posted['payment_status'] ), $order, $posted );
}
}
}
/**
* Check PayPal IPN validity.
*/
public function validate_ipn() {
WC_Gateway_Paypal::log( 'Checking IPN response is valid' );
// Get received values from post data.
$validate_ipn = wp_unslash( $_POST ); // WPCS: CSRF ok, input var ok.
$validate_ipn['cmd'] = '_notify-validate';
// Send back post vars to paypal.
$params = array(
'body' => $validate_ipn,
'timeout' => 60,
'httpversion' => '1.1',
'compress' => false,
'decompress' => false,
'user-agent' => 'WooCommerce/' . WC()->version,
);
// Post back to get a response.
$response = wp_safe_remote_post( $this->sandbox ? 'https://www.sandbox.paypal.com/cgi-bin/webscr' : 'https://www.paypal.com/cgi-bin/webscr', $params );
WC_Gateway_Paypal::log( 'IPN Response: ' . wc_print_r( $response, true ) );
// Check to see if the request was valid.
if ( ! is_wp_error( $response ) && $response['response']['code'] >= 200 && $response['response']['code'] < 300 && strstr( $response['body'], 'VERIFIED' ) ) {
WC_Gateway_Paypal::log( 'Received valid response from PayPal IPN' );
return true;
}
WC_Gateway_Paypal::log( 'Received invalid response from PayPal IPN' );
if ( is_wp_error( $response ) ) {
WC_Gateway_Paypal::log( 'Error response: ' . $response->get_error_message() );
}
return false;
}
/**
* Check for a valid transaction type.
*
* @param string $txn_type Transaction type.
*/
protected function validate_transaction_type( $txn_type ) {
$accepted_types = array( 'cart', 'instant', 'express_checkout', 'web_accept', 'masspay', 'send_money', 'paypal_here' );
if ( ! in_array( strtolower( $txn_type ), $accepted_types, true ) ) {
WC_Gateway_Paypal::log( 'Aborting, Invalid type:' . $txn_type );
exit;
}
}
/**
* Check currency from IPN matches the order.
*
* @param WC_Order $order Order object.
* @param string $currency Currency code.
*/
protected function validate_currency( $order, $currency ) {
if ( $order->get_currency() !== $currency ) {
WC_Gateway_Paypal::log( 'Payment error: Currencies do not match (sent "' . $order->get_currency() . '" | returned "' . $currency . '")' );
/* translators: %s: currency code. */
$order->update_status( 'on-hold', sprintf( __( 'Validation error: PayPal currencies do not match (code %s).', 'woocommerce' ), $currency ) );
exit;
}
}
/**
* Check payment amount from IPN matches the order.
*
* @param WC_Order $order Order object.
* @param int $amount Amount to validate.
*/
protected function validate_amount( $order, $amount ) {
if ( number_format( $order->get_total(), 2, '.', '' ) !== number_format( $amount, 2, '.', '' ) ) {
WC_Gateway_Paypal::log( 'Payment error: Amounts do not match (gross ' . $amount . ')' );
/* translators: %s: Amount. */
$order->update_status( 'on-hold', sprintf( __( 'Validation error: PayPal amounts do not match (gross %s).', 'woocommerce' ), $amount ) );
exit;
}
}
/**
* Check receiver email from PayPal. If the receiver email in the IPN is different than what is stored in.
* WooCommerce -> Settings -> Checkout -> PayPal, it will log an error about it.
*
* @param WC_Order $order Order object.
* @param string $receiver_email Email to validate.
*/
protected function validate_receiver_email( $order, $receiver_email ) {
if ( strcasecmp( trim( $receiver_email ), trim( $this->receiver_email ) ) !== 0 ) {
WC_Gateway_Paypal::log( "IPN Response is for another account: {$receiver_email}. Your email is {$this->receiver_email}" );
/* translators: %s: email address . */
$order->update_status( 'on-hold', sprintf( __( 'Validation error: PayPal IPN response from a different email address (%s).', 'woocommerce' ), $receiver_email ) );
exit;
}
}
/**
* Handle a completed payment.
*
* @param WC_Order $order Order object.
* @param array $posted Posted data.
*/
protected function payment_status_completed( $order, $posted ) {
if ( $order->has_status( wc_get_is_paid_statuses() ) ) {
WC_Gateway_Paypal::log( 'Aborting, Order #' . $order->get_id() . ' is already complete.' );
exit;
}
$this->validate_transaction_type( $posted['txn_type'] );
$this->validate_currency( $order, $posted['mc_currency'] );
$this->validate_amount( $order, $posted['mc_gross'] );
$this->validate_receiver_email( $order, $posted['receiver_email'] );
$this->save_paypal_meta_data( $order, $posted );
if ( 'completed' === $posted['payment_status'] ) {
if ( $order->has_status( 'cancelled' ) ) {
$this->payment_status_paid_cancelled_order( $order, $posted );
}
$this->payment_complete( $order, ( ! empty( $posted['txn_id'] ) ? wc_clean( $posted['txn_id'] ) : '' ), __( 'IPN payment completed', 'woocommerce' ) );
if ( ! empty( $posted['mc_fee'] ) ) {
// Log paypal transaction fee.
update_post_meta( $order->get_id(), 'PayPal Transaction Fee', wc_clean( $posted['mc_fee'] ) );
}
} else {
if ( 'authorization' === $posted['pending_reason'] ) {
$this->payment_on_hold( $order, __( 'Payment authorized. Change payment status to processing or complete to capture funds.', 'woocommerce' ) );
} else {
/* translators: %s: pending reason. */
$this->payment_on_hold( $order, sprintf( __( 'Payment pending (%s).', 'woocommerce' ), $posted['pending_reason'] ) );
}
}
}
/**
* Handle a pending payment.
*
* @param WC_Order $order Order object.
* @param array $posted Posted data.
*/
protected function payment_status_pending( $order, $posted ) {
$this->payment_status_completed( $order, $posted );
}
/**
* Handle a failed payment.
*
* @param WC_Order $order Order object.
* @param array $posted Posted data.
*/
protected function payment_status_failed( $order, $posted ) {
/* translators: %s: payment status. */
$order->update_status( 'failed', sprintf( __( 'Payment %s via IPN.', 'woocommerce' ), wc_clean( $posted['payment_status'] ) ) );
}
/**
* Handle a denied payment.
*
* @param WC_Order $order Order object.
* @param array $posted Posted data.
*/
protected function payment_status_denied( $order, $posted ) {
$this->payment_status_failed( $order, $posted );
}
/**
* Handle an expired payment.
*
* @param WC_Order $order Order object.
* @param array $posted Posted data.
*/
protected function payment_status_expired( $order, $posted ) {
$this->payment_status_failed( $order, $posted );
}
/**
* Handle a voided payment.
*
* @param WC_Order $order Order object.
* @param array $posted Posted data.
*/
protected function payment_status_voided( $order, $posted ) {
$this->payment_status_failed( $order, $posted );
}
/**
* When a user cancelled order is marked paid.
*
* @param WC_Order $order Order object.
* @param array $posted Posted data.
*/
protected function payment_status_paid_cancelled_order( $order, $posted ) {
$this->send_ipn_email_notification(
/* translators: %s: order link. */
sprintf( __( 'Payment for cancelled order %s received', 'woocommerce' ), '<a class="link" href="' . esc_url( $order->get_edit_order_url() ) . '">' . $order->get_order_number() . '</a>' ),
/* translators: %s: order ID. */
sprintf( __( 'Order #%s has been marked paid by PayPal IPN, but was previously cancelled. Admin handling required.', 'woocommerce' ), $order->get_order_number() )
);
}
/**
* Handle a refunded order.
*
* @param WC_Order $order Order object.
* @param array $posted Posted data.
*/
protected function payment_status_refunded( $order, $posted ) {
// Only handle full refunds, not partial.
if ( $order->get_total() === wc_format_decimal( $posted['mc_gross'] * -1 ) ) {
/* translators: %s: payment status. */
$order->update_status( 'refunded', sprintf( __( 'Payment %s via IPN.', 'woocommerce' ), strtolower( $posted['payment_status'] ) ) );
$this->send_ipn_email_notification(
/* translators: %s: order link. */
sprintf( __( 'Payment for order %s refunded', 'woocommerce' ), '<a class="link" href="' . esc_url( $order->get_edit_order_url() ) . '">' . $order->get_order_number() . '</a>' ),
/* translators: %1$s: order ID, %2$s: reason code. */
sprintf( __( 'Order #%1$s has been marked as refunded - PayPal reason code: %2$s', 'woocommerce' ), $order->get_order_number(), $posted['reason_code'] )
);
}
}
/**
* Handle a reversal.
*
* @param WC_Order $order Order object.
* @param array $posted Posted data.
*/
protected function payment_status_reversed( $order, $posted ) {
/* translators: %s: payment status. */
$order->update_status( 'on-hold', sprintf( __( 'Payment %s via IPN.', 'woocommerce' ), wc_clean( $posted['payment_status'] ) ) );
$this->send_ipn_email_notification(
/* translators: %s: order link. */
sprintf( __( 'Payment for order %s reversed', 'woocommerce' ), '<a class="link" href="' . esc_url( $order->get_edit_order_url() ) . '">' . $order->get_order_number() . '</a>' ),
/* translators: %1$s: order ID, %2$s: reason code. */
sprintf( __( 'Order #%1$s has been marked on-hold due to a reversal - PayPal reason code: %2$s', 'woocommerce' ), $order->get_order_number(), wc_clean( $posted['reason_code'] ) )
);
}
/**
* Handle a cancelled reversal.
*
* @param WC_Order $order Order object.
* @param array $posted Posted data.
*/
protected function payment_status_canceled_reversal( $order, $posted ) {
$this->send_ipn_email_notification(
/* translators: %s: order link. */
sprintf( __( 'Reversal cancelled for order #%s', 'woocommerce' ), $order->get_order_number() ),
/* translators: %1$s: order ID, %2$s: order link. */
sprintf( __( 'Order #%1$s has had a reversal cancelled. Please check the status of payment and update the order status accordingly here: %2$s', 'woocommerce' ), $order->get_order_number(), esc_url( $order->get_edit_order_url() ) )
);
}
/**
* Save important data from the IPN to the order.
*
* @param WC_Order $order Order object.
* @param array $posted Posted data.
*/
protected function save_paypal_meta_data( $order, $posted ) {
if ( ! empty( $posted['payment_type'] ) ) {
update_post_meta( $order->get_id(), 'Payment type', wc_clean( $posted['payment_type'] ) );
}
if ( ! empty( $posted['txn_id'] ) ) {
update_post_meta( $order->get_id(), '_transaction_id', wc_clean( $posted['txn_id'] ) );
}
if ( ! empty( $posted['payment_status'] ) ) {
update_post_meta( $order->get_id(), '_paypal_status', wc_clean( $posted['payment_status'] ) );
}
}
/**
* Send a notification to the user handling orders.
*
* @param string $subject Email subject.
* @param string $message Email message.
*/
protected function send_ipn_email_notification( $subject, $message ) {
$new_order_settings = get_option( 'woocommerce_new_order_settings', array() );
$mailer = WC()->mailer();
$message = $mailer->wrap_message( $subject, $message );
$woocommerce_paypal_settings = get_option( 'woocommerce_paypal_settings' );
if ( ! empty( $woocommerce_paypal_settings['ipn_notification'] ) && 'no' === $woocommerce_paypal_settings['ipn_notification'] ) {
return;
}
$mailer->send( ! empty( $new_order_settings['recipient'] ) ? $new_order_settings['recipient'] : get_option( 'admin_email' ), strip_tags( $subject ), $message );
}
}

View File

@@ -0,0 +1,136 @@
<?php
/**
* Class WC_Gateway_Paypal_PDT_Handler file.
*
* @package WooCommerce\Gateways
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
require_once dirname( __FILE__ ) . '/class-wc-gateway-paypal-response.php';
/**
* Handle PDT Responses from PayPal.
*/
class WC_Gateway_Paypal_PDT_Handler extends WC_Gateway_Paypal_Response {
/**
* Identity token for PDT support
*
* @var string
*/
protected $identity_token;
/**
* Constructor.
*
* @param bool $sandbox Whether to use sandbox mode or not.
* @param string $identity_token Identity token for PDT support.
*/
public function __construct( $sandbox = false, $identity_token = '' ) {
add_action( 'woocommerce_thankyou_paypal', array( $this, 'check_response' ) );
$this->identity_token = $identity_token;
$this->sandbox = $sandbox;
}
/**
* Validate a PDT transaction to ensure its authentic.
*
* @param string $transaction TX ID.
* @return bool|array False or result array if successful and valid.
*/
protected function validate_transaction( $transaction ) {
$pdt = array(
'body' => array(
'cmd' => '_notify-synch',
'tx' => $transaction,
'at' => $this->identity_token,
),
'timeout' => 60,
'httpversion' => '1.1',
'user-agent' => 'WooCommerce/' . WC_VERSION,
);
// Post back to get a response.
$response = wp_safe_remote_post( $this->sandbox ? 'https://www.sandbox.paypal.com/cgi-bin/webscr' : 'https://www.paypal.com/cgi-bin/webscr', $pdt );
if ( is_wp_error( $response ) || strpos( $response['body'], 'SUCCESS' ) !== 0 ) {
return false;
}
// Parse transaction result data.
$transaction_result = array_map( 'wc_clean', array_map( 'urldecode', explode( "\n", $response['body'] ) ) );
$transaction_results = array();
foreach ( $transaction_result as $line ) {
$line = explode( '=', $line );
$transaction_results[ $line[0] ] = isset( $line[1] ) ? $line[1] : '';
}
if ( ! empty( $transaction_results['charset'] ) && function_exists( 'iconv' ) ) {
foreach ( $transaction_results as $key => $value ) {
$transaction_results[ $key ] = iconv( $transaction_results['charset'], 'utf-8', $value );
}
}
return $transaction_results;
}
/**
* Check Response for PDT.
*/
public function check_response() {
if ( empty( $_REQUEST['cm'] ) || empty( $_REQUEST['tx'] ) || empty( $_REQUEST['st'] ) ) { // WPCS: Input var ok, CSRF ok, sanitization ok.
return;
}
$order_id = wc_clean( wp_unslash( $_REQUEST['cm'] ) ); // WPCS: input var ok, CSRF ok, sanitization ok.
$status = wc_clean( strtolower( wp_unslash( $_REQUEST['st'] ) ) ); // WPCS: input var ok, CSRF ok, sanitization ok.
$amount = wc_clean( wp_unslash( $_REQUEST['amt'] ) ); // WPCS: input var ok, CSRF ok, sanitization ok.
$transaction = wc_clean( wp_unslash( $_REQUEST['tx'] ) ); // WPCS: input var ok, CSRF ok, sanitization ok.
$order = $this->get_paypal_order( $order_id );
if ( ! $order || ! $order->has_status( 'pending' ) ) {
return false;
}
$transaction_result = $this->validate_transaction( $transaction );
if ( $transaction_result ) {
WC_Gateway_Paypal::log( 'PDT Transaction Status: ' . wc_print_r( $status, true ) );
update_post_meta( $order->get_id(), '_paypal_status', $status );
update_post_meta( $order->get_id(), '_transaction_id', $transaction );
if ( 'completed' === $status ) {
if ( $order->get_total() !== $amount ) {
WC_Gateway_Paypal::log( 'Payment error: Amounts do not match (amt ' . $amount . ')', 'error' );
/* translators: 1: Payment amount */
$this->payment_on_hold( $order, sprintf( __( 'Validation error: PayPal amounts do not match (amt %s).', 'woocommerce' ), $amount ) );
} else {
$this->payment_complete( $order, $transaction, __( 'PDT payment completed', 'woocommerce' ) );
// Log paypal transaction fee and payment type.
if ( ! empty( $transaction_result['mc_fee'] ) ) {
update_post_meta( $order->get_id(), 'PayPal Transaction Fee', $transaction_result['mc_fee'] );
}
if ( ! empty( $transaction_result['payment_type'] ) ) {
update_post_meta( $order->get_id(), 'Payment type', $transaction_result['payment_type'] );
}
}
} else {
if ( 'authorization' === $transaction_result['pending_reason'] ) {
$this->payment_on_hold( $order, __( 'Payment authorized. Change payment status to processing or complete to capture funds.', 'woocommerce' ) );
} else {
/* translators: 1: Pending reason */
$this->payment_on_hold( $order, sprintf( __( 'Payment pending (%s).', 'woocommerce' ), $transaction_result['pending_reason'] ) );
}
}
} else {
WC_Gateway_Paypal::log( 'Received invalid response from PayPal PDT' );
}
}
}

View File

@@ -0,0 +1,552 @@
<?php
/**
* Class WC_Gateway_Paypal_Request file.
*
* @package WooCommerce\Gateways
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Generates requests to send to PayPal.
*/
class WC_Gateway_Paypal_Request {
/**
* Stores line items to send to PayPal.
*
* @var array
*/
protected $line_items = array();
/**
* Pointer to gateway making the request.
*
* @var WC_Gateway_Paypal
*/
protected $gateway;
/**
* Endpoint for requests from PayPal.
*
* @var string
*/
protected $notify_url;
/**
* Endpoint for requests to PayPal.
*
* @var string
*/
protected $endpoint;
/**
* Constructor.
*
* @param WC_Gateway_Paypal $gateway Paypal gateway object.
*/
public function __construct( $gateway ) {
$this->gateway = $gateway;
$this->notify_url = WC()->api_request_url( 'WC_Gateway_Paypal' );
}
/**
* Get the PayPal request URL for an order.
*
* @param WC_Order $order Order object.
* @param bool $sandbox Whether to use sandbox mode or not.
* @return string
*/
public function get_request_url( $order, $sandbox = false ) {
$this->endpoint = $sandbox ? 'https://www.sandbox.paypal.com/cgi-bin/webscr?test_ipn=1&' : 'https://www.paypal.com/cgi-bin/webscr?';
$paypal_args = $this->get_paypal_args( $order );
$mask = array(
'first_name' => '***',
'last_name' => '***',
'address1' => '***',
'address2' => '***',
'city' => '***',
'state' => '***',
'zip' => '***',
'country' => '***',
'email' => '***@***',
'night_phone_a' => '***',
'night_phone_b' => '***',
'night_phone_c' => '***',
);
WC_Gateway_Paypal::log( 'PayPal Request Args for order ' . $order->get_order_number() . ': ' . wc_print_r( array_merge( $paypal_args, array_intersect_key( $mask, $paypal_args ) ), true ) );
return $this->endpoint . http_build_query( $paypal_args, '', '&' );
}
/**
* Limit length of an arg.
*
* @param string $string Argument to limit.
* @param integer $limit Limit size in characters.
* @return string
*/
protected function limit_length( $string, $limit = 127 ) {
// As the output is to be used in http_build_query which applies URL encoding, the string needs to be
// cut as if it was URL-encoded, but returned non-encoded (it will be encoded by http_build_query later).
$url_encoded_str = rawurlencode( $string );
if ( strlen( $url_encoded_str ) > $limit ) {
$string = rawurldecode( substr( $url_encoded_str, 0, $limit - 3 ) . '...' );
}
return $string;
}
/**
* Get transaction args for paypal request, except for line item args.
*
* @param WC_Order $order Order object.
* @return array
*/
protected function get_transaction_args( $order ) {
return array_merge(
array(
'cmd' => '_cart',
'business' => $this->gateway->get_option( 'email' ),
'no_note' => 1,
'currency_code' => get_woocommerce_currency(),
'charset' => 'utf-8',
'rm' => is_ssl() ? 2 : 1,
'upload' => 1,
'return' => esc_url_raw( add_query_arg( 'utm_nooverride', '1', $this->gateway->get_return_url( $order ) ) ),
'cancel_return' => esc_url_raw( $order->get_cancel_order_url_raw() ),
'page_style' => $this->gateway->get_option( 'page_style' ),
'image_url' => esc_url_raw( $this->gateway->get_option( 'image_url' ) ),
'paymentaction' => $this->gateway->get_option( 'paymentaction' ),
'bn' => 'WooThemes_Cart',
'invoice' => $this->limit_length( $this->gateway->get_option( 'invoice_prefix' ) . $order->get_order_number(), 127 ),
'custom' => wp_json_encode(
array(
'order_id' => $order->get_id(),
'order_key' => $order->get_order_key(),
)
),
'notify_url' => $this->limit_length( $this->notify_url, 255 ),
'first_name' => $this->limit_length( $order->get_billing_first_name(), 32 ),
'last_name' => $this->limit_length( $order->get_billing_last_name(), 64 ),
'address1' => $this->limit_length( $order->get_billing_address_1(), 100 ),
'address2' => $this->limit_length( $order->get_billing_address_2(), 100 ),
'city' => $this->limit_length( $order->get_billing_city(), 40 ),
'state' => $this->get_paypal_state( $order->get_billing_country(), $order->get_billing_state() ),
'zip' => $this->limit_length( wc_format_postcode( $order->get_billing_postcode(), $order->get_billing_country() ), 32 ),
'country' => $this->limit_length( $order->get_billing_country(), 2 ),
'email' => $this->limit_length( $order->get_billing_email() ),
),
$this->get_phone_number_args( $order ),
$this->get_shipping_args( $order )
);
}
/**
* If the default request with line items is too long, generate a new one with only one line item.
*
* If URL is longer than 2,083 chars, ignore line items and send cart to Paypal as a single item.
* One item's name can only be 127 characters long, so the URL should not be longer than limit.
* URL character limit via:
* https://support.microsoft.com/en-us/help/208427/maximum-url-length-is-2-083-characters-in-internet-explorer.
*
* @param WC_Order $order Order to be sent to Paypal.
* @param array $paypal_args Arguments sent to Paypal in the request.
* @return array
*/
protected function fix_request_length( $order, $paypal_args ) {
$max_paypal_length = 2083;
$query_candidate = http_build_query( $paypal_args, '', '&' );
if ( strlen( $this->endpoint . $query_candidate ) <= $max_paypal_length ) {
return $paypal_args;
}
return apply_filters(
'woocommerce_paypal_args', array_merge(
$this->get_transaction_args( $order ),
$this->get_line_item_args( $order, true )
), $order
);
}
/**
* Get PayPal Args for passing to PP.
*
* @param WC_Order $order Order object.
* @return array
*/
protected function get_paypal_args( $order ) {
WC_Gateway_Paypal::log( 'Generating payment form for order ' . $order->get_order_number() . '. Notify URL: ' . $this->notify_url );
$paypal_args = apply_filters(
'woocommerce_paypal_args', array_merge(
$this->get_transaction_args( $order ),
$this->get_line_item_args( $order )
), $order
);
return $this->fix_request_length( $order, $paypal_args );
}
/**
* Get phone number args for paypal request.
*
* @param WC_Order $order Order object.
* @return array
*/
protected function get_phone_number_args( $order ) {
if ( in_array( $order->get_billing_country(), array( 'US', 'CA' ), true ) ) {
$phone_number = str_replace( array( '(', '-', ' ', ')', '.' ), '', $order->get_billing_phone() );
$phone_number = ltrim( $phone_number, '+1' );
$phone_args = array(
'night_phone_a' => substr( $phone_number, 0, 3 ),
'night_phone_b' => substr( $phone_number, 3, 3 ),
'night_phone_c' => substr( $phone_number, 6, 4 ),
);
} else {
$phone_args = array(
'night_phone_b' => $order->get_billing_phone(),
);
}
return $phone_args;
}
/**
* Get shipping args for paypal request.
*
* @param WC_Order $order Order object.
* @return array
*/
protected function get_shipping_args( $order ) {
$shipping_args = array();
if ( 'yes' === $this->gateway->get_option( 'send_shipping' ) ) {
$shipping_args['address_override'] = $this->gateway->get_option( 'address_override' ) === 'yes' ? 1 : 0;
$shipping_args['no_shipping'] = 0;
// If we are sending shipping, send shipping address instead of billing.
$shipping_args['first_name'] = $this->limit_length( $order->get_shipping_first_name(), 32 );
$shipping_args['last_name'] = $this->limit_length( $order->get_shipping_last_name(), 64 );
$shipping_args['address1'] = $this->limit_length( $order->get_shipping_address_1(), 100 );
$shipping_args['address2'] = $this->limit_length( $order->get_shipping_address_2(), 100 );
$shipping_args['city'] = $this->limit_length( $order->get_shipping_city(), 40 );
$shipping_args['state'] = $this->get_paypal_state( $order->get_shipping_country(), $order->get_shipping_state() );
$shipping_args['country'] = $this->limit_length( $order->get_shipping_country(), 2 );
$shipping_args['zip'] = $this->limit_length( wc_format_postcode( $order->get_shipping_postcode(), $order->get_shipping_country() ), 32 );
} else {
$shipping_args['no_shipping'] = 1;
}
return $shipping_args;
}
/**
* Get shipping cost line item args for paypal request.
*
* @param WC_Order $order Order object.
* @param bool $force_one_line_item Whether one line item was forced by validation or URL length.
* @return array
*/
protected function get_shipping_cost_line_item( $order, $force_one_line_item ) {
$line_item_args = array();
$shipping_total = $order->get_shipping_total();
if ( $force_one_line_item ) {
$shipping_total += $order->get_shipping_tax();
}
// Add shipping costs. Paypal ignores anything over 5 digits (999.99 is the max).
// We also check that shipping is not the **only** cost as PayPal won't allow payment
// if the items have no cost.
if ( $order->get_shipping_total() > 0 && $order->get_shipping_total() < 999.99 && $this->number_format( $order->get_shipping_total() + $order->get_shipping_tax(), $order ) !== $this->number_format( $order->get_total(), $order ) ) {
$line_item_args['shipping_1'] = $this->number_format( $shipping_total, $order );
} elseif ( $order->get_shipping_total() > 0 ) {
/* translators: %s: Order shipping method */
$this->add_line_item( sprintf( __( 'Shipping via %s', 'woocommerce' ), $order->get_shipping_method() ), 1, $this->number_format( $shipping_total, $order ) );
}
return $line_item_args;
}
/**
* Get line item args for paypal request as a single line item.
*
* @param WC_Order $order Order object.
* @return array
*/
protected function get_line_item_args_single_item( $order ) {
$this->delete_line_items();
$all_items_name = $this->get_order_item_names( $order );
$this->add_line_item( $all_items_name ? $all_items_name : __( 'Order', 'woocommerce' ), 1, $this->number_format( $order->get_total() - $this->round( $order->get_shipping_total() + $order->get_shipping_tax(), $order ), $order ), $order->get_order_number() );
$line_item_args = $this->get_shipping_cost_line_item( $order, true );
return array_merge( $line_item_args, $this->get_line_items() );
}
/**
* Get line item args for paypal request.
*
* @param WC_Order $order Order object.
* @param bool $force_one_line_item Create only one item for this order.
* @return array
*/
protected function get_line_item_args( $order, $force_one_line_item = false ) {
if ( wc_tax_enabled() && wc_prices_include_tax() || ! $this->line_items_valid( $order ) ) {
$force_one_line_item = true;
}
$line_item_args = array();
if ( $force_one_line_item ) {
/**
* Send order as a single item.
*
* For shipping, we longer use shipping_1 because paypal ignores it if *any* shipping rules are within paypal, and paypal ignores anything over 5 digits (999.99 is the max).
*/
$line_item_args = $this->get_line_item_args_single_item( $order );
} else {
/**
* Passing a line item per product if supported.
*/
$this->prepare_line_items( $order );
$line_item_args['tax_cart'] = $this->number_format( $order->get_total_tax(), $order );
if ( $order->get_total_discount() > 0 ) {
$line_item_args['discount_amount_cart'] = $this->number_format( $this->round( $order->get_total_discount(), $order ), $order );
}
$line_item_args = array_merge( $line_item_args, $this->get_shipping_cost_line_item( $order, false ) );
$line_item_args = array_merge( $line_item_args, $this->get_line_items() );
}
return $line_item_args;
}
/**
* Get order item names as a string.
*
* @param WC_Order $order Order object.
* @return string
*/
protected function get_order_item_names( $order ) {
$item_names = array();
foreach ( $order->get_items() as $item ) {
$item_name = $item->get_name();
$item_meta = strip_tags(
wc_display_item_meta(
$item, array(
'before' => '',
'separator' => ', ',
'after' => '',
'echo' => false,
'autop' => false,
)
)
);
if ( $item_meta ) {
$item_name .= ' (' . $item_meta . ')';
}
$item_names[] = $item_name . ' x ' . $item->get_quantity();
}
return apply_filters( 'woocommerce_paypal_get_order_item_names', implode( ', ', $item_names ), $order );
}
/**
* Get order item names as a string.
*
* @param WC_Order $order Order object.
* @param WC_Order_Item $item Order item object.
* @return string
*/
protected function get_order_item_name( $order, $item ) {
$item_name = $item->get_name();
$item_meta = strip_tags(
wc_display_item_meta(
$item, array(
'before' => '',
'separator' => ', ',
'after' => '',
'echo' => false,
'autop' => false,
)
)
);
if ( $item_meta ) {
$item_name .= ' (' . $item_meta . ')';
}
return apply_filters( 'woocommerce_paypal_get_order_item_name', $item_name, $order, $item );
}
/**
* Return all line items.
*/
protected function get_line_items() {
return $this->line_items;
}
/**
* Remove all line items.
*/
protected function delete_line_items() {
$this->line_items = array();
}
/**
* Check if the order has valid line items to use for PayPal request.
*
* The line items are invalid in case of mismatch in totals or if any amount < 0.
*
* @param WC_Order $order Order to be examined.
* @return bool
*/
protected function line_items_valid( $order ) {
$negative_item_amount = false;
$calculated_total = 0;
// Products.
foreach ( $order->get_items( array( 'line_item', 'fee' ) ) as $item ) {
if ( 'fee' === $item['type'] ) {
$item_line_total = $this->number_format( $item['line_total'], $order );
$calculated_total += $item_line_total;
} else {
$item_line_total = $this->number_format( $order->get_item_subtotal( $item, false ), $order );
$calculated_total += $item_line_total * $item->get_quantity();
}
if ( $item_line_total < 0 ) {
$negative_item_amount = true;
}
}
$mismatched_totals = $this->number_format( $calculated_total + $order->get_total_tax() + $this->round( $order->get_shipping_total(), $order ) - $this->round( $order->get_total_discount(), $order ), $order ) !== $this->number_format( $order->get_total(), $order );
return ! $negative_item_amount && ! $mismatched_totals;
}
/**
* Get line items to send to paypal.
*
* @param WC_Order $order Order object.
*/
protected function prepare_line_items( $order ) {
$this->delete_line_items();
// Products.
foreach ( $order->get_items( array( 'line_item', 'fee' ) ) as $item ) {
if ( 'fee' === $item['type'] ) {
$item_line_total = $this->number_format( $item['line_total'], $order );
$this->add_line_item( $item->get_name(), 1, $item_line_total );
} else {
$product = $item->get_product();
$sku = $product ? $product->get_sku() : '';
$item_line_total = $this->number_format( $order->get_item_subtotal( $item, false ), $order );
$this->add_line_item( $this->get_order_item_name( $order, $item ), $item->get_quantity(), $item_line_total, $sku );
}
}
}
/**
* Add PayPal Line Item.
*
* @param string $item_name Item name.
* @param int $quantity Item quantity.
* @param float $amount Amount.
* @param string $item_number Item number.
*/
protected function add_line_item( $item_name, $quantity = 1, $amount = 0.0, $item_number = '' ) {
$index = ( count( $this->line_items ) / 4 ) + 1;
$item = apply_filters(
'woocommerce_paypal_line_item', array(
'item_name' => html_entity_decode( wc_trim_string( $item_name ? $item_name : __( 'Item', 'woocommerce' ), 127 ), ENT_NOQUOTES, 'UTF-8' ),
'quantity' => (int) $quantity,
'amount' => wc_float_to_string( (float) $amount ),
'item_number' => $item_number,
), $item_name, $quantity, $amount, $item_number
);
$this->line_items[ 'item_name_' . $index ] = $this->limit_length( $item['item_name'], 127 );
$this->line_items[ 'quantity_' . $index ] = $item['quantity'];
$this->line_items[ 'amount_' . $index ] = $item['amount'];
$this->line_items[ 'item_number_' . $index ] = $this->limit_length( $item['item_number'], 127 );
}
/**
* Get the state to send to paypal.
*
* @param string $cc Country two letter code.
* @param string $state State code.
* @return string
*/
protected function get_paypal_state( $cc, $state ) {
if ( 'US' === $cc ) {
return $state;
}
$states = WC()->countries->get_states( $cc );
if ( isset( $states[ $state ] ) ) {
return $states[ $state ];
}
return $state;
}
/**
* Check if currency has decimals.
*
* @param string $currency Currency to check.
* @return bool
*/
protected function currency_has_decimals( $currency ) {
if ( in_array( $currency, array( 'HUF', 'JPY', 'TWD' ), true ) ) {
return false;
}
return true;
}
/**
* Round prices.
*
* @param double $price Price to round.
* @param WC_Order $order Order object.
* @return double
*/
protected function round( $price, $order ) {
$precision = 2;
if ( ! $this->currency_has_decimals( $order->get_currency() ) ) {
$precision = 0;
}
return round( $price, $precision );
}
/**
* Format prices.
*
* @param float|int $price Price to format.
* @param WC_Order $order Order object.
* @return string
*/
protected function number_format( $price, $order ) {
$decimals = 2;
if ( ! $this->currency_has_decimals( $order->get_currency() ) ) {
$decimals = 0;
}
return number_format( $price, $decimals, '.', '' );
}
}

View File

@@ -0,0 +1,82 @@
<?php
/**
* Class WC_Gateway_Paypal_Response file.
*
* @package WooCommerce\Gateways
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Handles Responses.
*/
abstract class WC_Gateway_Paypal_Response {
/**
* Sandbox mode
*
* @var bool
*/
protected $sandbox = false;
/**
* Get the order from the PayPal 'Custom' variable.
*
* @param string $raw_custom JSON Data passed back by PayPal.
* @return bool|WC_Order object
*/
protected function get_paypal_order( $raw_custom ) {
// We have the data in the correct format, so get the order.
$custom = json_decode( $raw_custom );
if ( $custom && is_object( $custom ) ) {
$order_id = $custom->order_id;
$order_key = $custom->order_key;
} else {
// Nothing was found.
WC_Gateway_Paypal::log( 'Order ID and key were not found in "custom".', 'error' );
return false;
}
$order = wc_get_order( $order_id );
if ( ! $order ) {
// We have an invalid $order_id, probably because invoice_prefix has changed.
$order_id = wc_get_order_id_by_order_key( $order_key );
$order = wc_get_order( $order_id );
}
if ( ! $order || $order->get_order_key() !== $order_key ) {
WC_Gateway_Paypal::log( 'Order Keys do not match.', 'error' );
return false;
}
return $order;
}
/**
* Complete order, add transaction ID and note.
*
* @param WC_Order $order Order object.
* @param string $txn_id Transaction ID.
* @param string $note Payment note.
*/
protected function payment_complete( $order, $txn_id = '', $note = '' ) {
$order->add_order_note( $note );
$order->payment_complete( $txn_id );
WC()->cart->empty_cart();
}
/**
* Hold order and add note.
*
* @param WC_Order $order Order object.
* @param string $reason Reason why the payment is on hold.
*/
protected function payment_on_hold( $order, $reason = '' ) {
$order->update_status( 'on-hold', $reason );
wc_reduce_stock_levels( $order->get_id() );
WC()->cart->empty_cart();
}
}

View File

@@ -0,0 +1,186 @@
<?php
/**
* Settings for PayPal Gateway.
*
* @package WooCommerce/Classes/Payment
*/
defined( 'ABSPATH' ) || exit;
return array(
'enabled' => array(
'title' => __( 'Enable/Disable', 'woocommerce' ),
'type' => 'checkbox',
'label' => __( 'Enable PayPal Standard', 'woocommerce' ),
'default' => 'no',
),
'title' => array(
'title' => __( 'Title', 'woocommerce' ),
'type' => 'text',
'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ),
'default' => __( 'PayPal', 'woocommerce' ),
'desc_tip' => true,
),
'description' => array(
'title' => __( 'Description', 'woocommerce' ),
'type' => 'text',
'desc_tip' => true,
'description' => __( 'This controls the description which the user sees during checkout.', 'woocommerce' ),
'default' => __( "Pay via PayPal; you can pay with your credit card if you don't have a PayPal account.", 'woocommerce' ),
),
'email' => array(
'title' => __( 'PayPal email', 'woocommerce' ),
'type' => 'email',
'description' => __( 'Please enter your PayPal email address; this is needed in order to take payment.', 'woocommerce' ),
'default' => get_option( 'admin_email' ),
'desc_tip' => true,
'placeholder' => 'you@youremail.com',
),
'advanced' => array(
'title' => __( 'Advanced options', 'woocommerce' ),
'type' => 'title',
'description' => '',
),
'testmode' => array(
'title' => __( 'PayPal sandbox', 'woocommerce' ),
'type' => 'checkbox',
'label' => __( 'Enable PayPal sandbox', 'woocommerce' ),
'default' => 'no',
/* translators: %s: URL */
'description' => sprintf( __( 'PayPal sandbox can be used to test payments. Sign up for a <a href="%s">developer account</a>.', 'woocommerce' ), 'https://developer.paypal.com/' ),
),
'debug' => array(
'title' => __( 'Debug log', 'woocommerce' ),
'type' => 'checkbox',
'label' => __( 'Enable logging', 'woocommerce' ),
'default' => 'no',
/* translators: %s: URL */
'description' => sprintf( __( 'Log PayPal events, such as IPN requests, inside %s Note: this may log personal information. We recommend using this for debugging purposes only and deleting the logs when finished.', 'woocommerce' ), '<code>' . WC_Log_Handler_File::get_log_file_path( 'paypal' ) . '</code>' ),
),
'ipn_notification' => array(
'title' => __( 'IPN Email Notifications', 'woocommerce' ),
'type' => 'checkbox',
'label' => __( 'Enable IPN email notifications', 'woocommerce' ),
'default' => 'yes',
'description' => __( 'Send notifications when an IPN is received from PayPal indicating refunds, chargebacks and cancellations.', 'woocommerce' ),
),
'receiver_email' => array(
'title' => __( 'Receiver email', 'woocommerce' ),
'type' => 'email',
'description' => __( 'If your main PayPal email differs from the PayPal email entered above, input your main receiver email for your PayPal account here. This is used to validate IPN requests.', 'woocommerce' ),
'default' => '',
'desc_tip' => true,
'placeholder' => 'you@youremail.com',
),
'identity_token' => array(
'title' => __( 'PayPal identity token', 'woocommerce' ),
'type' => 'text',
'description' => __( 'Optionally enable "Payment Data Transfer" (Profile > Profile and Settings > My Selling Tools > Website Preferences) and then copy your identity token here. This will allow payments to be verified without the need for PayPal IPN.', 'woocommerce' ),
'default' => '',
'desc_tip' => true,
'placeholder' => '',
),
'invoice_prefix' => array(
'title' => __( 'Invoice prefix', 'woocommerce' ),
'type' => 'text',
'description' => __( 'Please enter a prefix for your invoice numbers. If you use your PayPal account for multiple stores ensure this prefix is unique as PayPal will not allow orders with the same invoice number.', 'woocommerce' ),
'default' => 'WC-',
'desc_tip' => true,
),
'send_shipping' => array(
'title' => __( 'Shipping details', 'woocommerce' ),
'type' => 'checkbox',
'label' => __( 'Send shipping details to PayPal instead of billing.', 'woocommerce' ),
'description' => __( 'PayPal allows us to send one address. If you are using PayPal for shipping labels you may prefer to send the shipping address rather than billing. Turning this option off may prevent PayPal Seller protection from applying.', 'woocommerce' ),
'default' => 'yes',
),
'address_override' => array(
'title' => __( 'Address override', 'woocommerce' ),
'type' => 'checkbox',
'label' => __( 'Enable "address_override" to prevent address information from being changed.', 'woocommerce' ),
'description' => __( 'PayPal verifies addresses therefore this setting can cause errors (we recommend keeping it disabled).', 'woocommerce' ),
'default' => 'no',
),
'paymentaction' => array(
'title' => __( 'Payment action', 'woocommerce' ),
'type' => 'select',
'class' => 'wc-enhanced-select',
'description' => __( 'Choose whether you wish to capture funds immediately or authorize payment only.', 'woocommerce' ),
'default' => 'sale',
'desc_tip' => true,
'options' => array(
'sale' => __( 'Capture', 'woocommerce' ),
'authorization' => __( 'Authorize', 'woocommerce' ),
),
),
'page_style' => array(
'title' => __( 'Page style', 'woocommerce' ),
'type' => 'text',
'description' => __( 'Optionally enter the name of the page style you wish to use. These are defined within your PayPal account. This affects classic PayPal checkout screens.', 'woocommerce' ),
'default' => '',
'desc_tip' => true,
'placeholder' => __( 'Optional', 'woocommerce' ),
),
'image_url' => array(
'title' => __( 'Image url', 'woocommerce' ),
'type' => 'text',
'description' => __( 'Optionally enter the URL to a 150x50px image displayed as your logo in the upper left corner of the PayPal checkout pages.', 'woocommerce' ),
'default' => '',
'desc_tip' => true,
'placeholder' => __( 'Optional', 'woocommerce' ),
),
'api_details' => array(
'title' => __( 'API credentials', 'woocommerce' ),
'type' => 'title',
/* translators: %s: URL */
'description' => sprintf( __( 'Enter your PayPal API credentials to process refunds via PayPal. Learn how to access your <a href="%s">PayPal API Credentials</a>.', 'woocommerce' ), 'https://developer.paypal.com/webapps/developer/docs/classic/api/apiCredentials/#create-an-api-signature' ),
),
'api_username' => array(
'title' => __( 'Live API username', 'woocommerce' ),
'type' => 'text',
'description' => __( 'Get your API credentials from PayPal.', 'woocommerce' ),
'default' => '',
'desc_tip' => true,
'placeholder' => __( 'Optional', 'woocommerce' ),
),
'api_password' => array(
'title' => __( 'Live API password', 'woocommerce' ),
'type' => 'password',
'description' => __( 'Get your API credentials from PayPal.', 'woocommerce' ),
'default' => '',
'desc_tip' => true,
'placeholder' => __( 'Optional', 'woocommerce' ),
),
'api_signature' => array(
'title' => __( 'Live API signature', 'woocommerce' ),
'type' => 'text',
'description' => __( 'Get your API credentials from PayPal.', 'woocommerce' ),
'default' => '',
'desc_tip' => true,
'placeholder' => __( 'Optional', 'woocommerce' ),
),
'sandbox_api_username' => array(
'title' => __( 'Sandbox API username', 'woocommerce' ),
'type' => 'text',
'description' => __( 'Get your API credentials from PayPal.', 'woocommerce' ),
'default' => '',
'desc_tip' => true,
'placeholder' => __( 'Optional', 'woocommerce' ),
),
'sandbox_api_password' => array(
'title' => __( 'Sandbox API password', 'woocommerce' ),
'type' => 'password',
'description' => __( 'Get your API credentials from PayPal.', 'woocommerce' ),
'default' => '',
'desc_tip' => true,
'placeholder' => __( 'Optional', 'woocommerce' ),
),
'sandbox_api_signature' => array(
'title' => __( 'Sandbox API signature', 'woocommerce' ),
'type' => 'text',
'description' => __( 'Get your API credentials from PayPal.', 'woocommerce' ),
'default' => '',
'desc_tip' => true,
'placeholder' => __( 'Optional', 'woocommerce' ),
),
);

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -0,0 +1,118 @@
/*global Simplify_commerce_params, SimplifyCommerce */
(function ( $ ) {
// Form handler
function simplifyFormHandler() {
var $form = $( 'form.checkout, form#order_review, form#add_payment_method' );
if ( ( $( '#payment_method_simplify_commerce' ).is( ':checked' ) && 'new' === $( 'input[name="wc-simplify_commerce-payment-token"]:checked' ).val() ) || ( '1' === $( '#woocommerce_add_payment_method' ).val() ) ) {
if ( 0 === $( 'input.simplify-token' ).length ) {
$form.block({
message: null,
overlayCSS: {
background: '#fff',
opacity: 0.6
}
});
var card = $( '#simplify_commerce-card-number' ).val(),
cvc = $( '#simplify_commerce-card-cvc' ).val(),
expiry = $.payment.cardExpiryVal( $( '#simplify_commerce-card-expiry' ).val() ),
address1 = $form.find( '#billing_address_1' ).val() || '',
address2 = $form.find( '#billing_address_2' ).val() || '',
addressCountry = $form.find( '#billing_country' ).val() || '',
addressState = $form.find( '#billing_state' ).val() || '',
addressCity = $form.find( '#billing_city' ).val() || '',
addressZip = $form.find( '#billing_postcode' ).val() || '';
addressZip = addressZip.replace( /-/g, '' );
card = card.replace( /\s/g, '' );
SimplifyCommerce.generateToken({
key: Simplify_commerce_params.key,
card: {
number: card,
cvc: cvc,
expMonth: expiry.month,
expYear: ( expiry.year - 2000 ),
addressLine1: address1,
addressLine2: address2,
addressCountry: addressCountry,
addressState: addressState,
addressZip: addressZip,
addressCity: addressCity
}
}, simplifyResponseHandler );
// Prevent the form from submitting
return false;
}
}
return true;
}
// Handle Simplify response
function simplifyResponseHandler( data ) {
var $form = $( 'form.checkout, form#order_review, form#add_payment_method' ),
ccForm = $( '#wc-simplify_commerce-cc-form' );
if ( data.error ) {
// Show the errors on the form
$( '.woocommerce-error, .simplify-token', ccForm ).remove();
$form.unblock();
// Show any validation errors
if ( 'validation' === data.error.code ) {
var fieldErrors = data.error.fieldErrors,
fieldErrorsLength = fieldErrors.length,
errorList = '';
for ( var i = 0; i < fieldErrorsLength; i++ ) {
errorList += '<li>' + Simplify_commerce_params[ fieldErrors[i].field ] + ' ' + Simplify_commerce_params.is_invalid + ' - ' + fieldErrors[i].message + '.</li>';
}
ccForm.prepend( '<ul class="woocommerce-error">' + errorList + '</ul>' );
}
} else {
// Insert the token into the form so it gets submitted to the server
ccForm.append( '<input type="hidden" class="simplify-token" name="simplify_token" value="' + data.id + '"/>' );
$form.submit();
}
}
$( function () {
$( document.body ).on( 'checkout_error', function () {
$( '.simplify-token' ).remove();
});
/* Checkout Form */
$( 'form.checkout' ).on( 'checkout_place_order_simplify_commerce', function () {
return simplifyFormHandler();
});
/* Pay Page Form */
$( 'form#order_review' ).on( 'submit', function () {
return simplifyFormHandler();
});
/* Pay Page Form */
$( 'form#add_payment_method' ).on( 'submit', function () {
return simplifyFormHandler();
});
/* Both Forms */
$( 'form.checkout, form#order_review, form#add_payment_method' ).on( 'change', '#wc-simplify_commerce-cc-form input', function() {
$( '.simplify-token' ).remove();
});
});
}( jQuery ) );

View File

@@ -0,0 +1 @@
!function(e){function r(){var r=e("form.checkout, form#order_review, form#add_payment_method");if((e("#payment_method_simplify_commerce").is(":checked")&&"new"===e('input[name="wc-simplify_commerce-payment-token"]:checked').val()||"1"===e("#woocommerce_add_payment_method").val())&&0===e("input.simplify-token").length){r.block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var i=e("#simplify_commerce-card-number").val(),m=e("#simplify_commerce-card-cvc").val(),c=e.payment.cardExpiryVal(e("#simplify_commerce-card-expiry").val()),n=r.find("#billing_address_1").val()||"",a=r.find("#billing_address_2").val()||"",t=r.find("#billing_country").val()||"",d=r.find("#billing_state").val()||"",l=r.find("#billing_city").val()||"",f=r.find("#billing_postcode").val()||"";return f=f.replace(/-/g,""),i=i.replace(/\s/g,""),SimplifyCommerce.generateToken({key:Simplify_commerce_params.key,card:{number:i,cvc:m,expMonth:c.month,expYear:c.year-2e3,addressLine1:n,addressLine2:a,addressCountry:t,addressState:d,addressZip:f,addressCity:l}},o),!1}return!0}function o(r){var o=e("form.checkout, form#order_review, form#add_payment_method"),i=e("#wc-simplify_commerce-cc-form");if(r.error){if(e(".woocommerce-error, .simplify-token",i).remove(),o.unblock(),"validation"===r.error.code){for(var m=r.error.fieldErrors,c=m.length,n="",a=0;a<c;a++)n+="<li>"+Simplify_commerce_params[m[a].field]+" "+Simplify_commerce_params.is_invalid+" - "+m[a].message+".</li>";i.prepend('<ul class="woocommerce-error">'+n+"</ul>")}}else i.append('<input type="hidden" class="simplify-token" name="simplify_token" value="'+r.id+'"/>'),o.submit()}e(function(){e(document.body).on("checkout_error",function(){e(".simplify-token").remove()}),e("form.checkout").on("checkout_place_order_simplify_commerce",function(){return r()}),e("form#order_review").on("submit",function(){return r()}),e("form#add_payment_method").on("submit",function(){return r()}),e("form.checkout, form#order_review, form#add_payment_method").on("change","#wc-simplify_commerce-cc-form input",function(){e(".simplify-token").remove()})})}(jQuery);

View File

@@ -0,0 +1,522 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Simplify Commerce Gateway for subscriptions.
*
* @class WC_Addons_Gateway_Simplify_Commerce
* @extends WC_Gateway_Simplify_Commerce
* @since 2.2.0
* @version 1.0.0
* @package WooCommerce/Classes/Payment
* @author WooThemes
*/
class WC_Addons_Gateway_Simplify_Commerce extends WC_Gateway_Simplify_Commerce {
/**
* Constructor.
*/
public function __construct() {
parent::__construct();
if ( class_exists( 'WC_Subscriptions_Order' ) ) {
add_action( 'woocommerce_scheduled_subscription_payment_' . $this->id, array( $this, 'scheduled_subscription_payment' ), 10, 2 );
add_action( 'woocommerce_subscription_failing_payment_method_updated_' . $this->id, array( $this, 'update_failing_payment_method' ), 10, 2 );
add_action( 'wcs_resubscribe_order_created', array( $this, 'delete_resubscribe_meta' ), 10 );
// Allow store managers to manually set Simplify as the payment method on a subscription
add_filter( 'woocommerce_subscription_payment_meta', array( $this, 'add_subscription_payment_meta' ), 10, 2 );
add_filter( 'woocommerce_subscription_validate_payment_meta', array( $this, 'validate_subscription_payment_meta' ), 10, 2 );
}
if ( class_exists( 'WC_Pre_Orders_Order' ) ) {
add_action( 'wc_pre_orders_process_pre_order_completion_payment_' . $this->id, array( $this, 'process_pre_order_release_payment' ) );
}
add_filter( 'woocommerce_simplify_commerce_hosted_args', array( $this, 'hosted_payment_args' ), 10, 2 );
add_action( 'woocommerce_api_wc_addons_gateway_simplify_commerce', array( $this, 'return_handler' ) );
}
/**
* Hosted payment args.
*
* @param array $args
* @param int $order_id
* @return array
*/
public function hosted_payment_args( $args, $order_id ) {
if ( ( $this->order_contains_subscription( $order_id ) ) || ( $this->order_contains_pre_order( $order_id ) && WC_Pre_Orders_Order::order_requires_payment_tokenization( $order_id ) ) ) {
$args['operation'] = 'create.token';
}
$args['redirect-url'] = WC()->api_request_url( 'WC_Addons_Gateway_Simplify_Commerce' );
return $args;
}
/**
* Check if order contains subscriptions.
*
* @param int $order_id
* @return bool
*/
protected function order_contains_subscription( $order_id ) {
return function_exists( 'wcs_order_contains_subscription' ) && ( wcs_order_contains_subscription( $order_id ) || wcs_order_contains_renewal( $order_id ) );
}
/**
* Check if order contains pre-orders.
*
* @param int $order_id
* @return bool
*/
protected function order_contains_pre_order( $order_id ) {
return class_exists( 'WC_Pre_Orders_Order' ) && WC_Pre_Orders_Order::order_contains_pre_order( $order_id );
}
/**
* Process the subscription.
*
* @param WC_Order $order
* @param string $cart_token
* @uses Simplify_ApiException
* @uses Simplify_BadRequestException
* @return array
* @throws Exception
*/
protected function process_subscription( $order, $cart_token = '' ) {
try {
if ( empty( $cart_token ) ) {
$error_msg = __( 'Please make sure your card details have been entered correctly and that your browser supports JavaScript.', 'woocommerce' );
if ( 'yes' == $this->sandbox ) {
$error_msg .= ' ' . __( 'Developers: Please make sure that you are including jQuery and there are no JavaScript errors on the page.', 'woocommerce' );
}
throw new Simplify_ApiException( $error_msg );
}
// Create customer
$customer = Simplify_Customer::createCustomer(
array(
'token' => $cart_token,
'email' => $order->get_billing_email(),
'name' => trim( $order->get_formatted_billing_full_name() ),
'reference' => $order->get_id(),
)
);
if ( is_object( $customer ) && '' != $customer->id ) {
$this->save_subscription_meta( $order->get_id(), $customer->id );
} else {
$error_msg = __( 'Error creating user in Simplify Commerce.', 'woocommerce' );
throw new Simplify_ApiException( $error_msg );
}
$payment_response = $this->process_subscription_payment( $order, $order->get_total() );
if ( is_wp_error( $payment_response ) ) {
throw new Exception( $payment_response->get_error_message() );
} else {
// Remove cart
WC()->cart->empty_cart();
// Return thank you page redirect
return array(
'result' => 'success',
'redirect' => $this->get_return_url( $order ),
);
}
} catch ( Simplify_ApiException $e ) {
if ( $e instanceof Simplify_BadRequestException && $e->hasFieldErrors() && $e->getFieldErrors() ) {
foreach ( $e->getFieldErrors() as $error ) {
wc_add_notice( $error->getFieldName() . ': "' . $error->getMessage() . '" (' . $error->getErrorCode() . ')', 'error' );
}
} else {
wc_add_notice( $e->getMessage(), 'error' );
}
return array(
'result' => 'fail',
'redirect' => '',
);
}
}
/**
* Store the customer and card IDs on the order and subscriptions in the order.
*
* @param int $order_id
* @param string $customer_id
*/
protected function save_subscription_meta( $order_id, $customer_id ) {
$customer_id = wc_clean( $customer_id );
update_post_meta( $order_id, '_simplify_customer_id', $customer_id );
// Also store it on the subscriptions being purchased in the order
foreach ( wcs_get_subscriptions_for_order( $order_id ) as $subscription ) {
update_post_meta( $subscription->id, '_simplify_customer_id', $customer_id );
}
}
/**
* Process the pre-order.
*
* @param WC_Order $order
* @param string $cart_token
* @uses Simplify_ApiException
* @uses Simplify_BadRequestException
* @return array
*/
protected function process_pre_order( $order, $cart_token = '' ) {
if ( WC_Pre_Orders_Order::order_requires_payment_tokenization( $order->get_id() ) ) {
try {
if ( $order->get_total() * 100 < 50 ) {
$error_msg = __( 'Sorry, the minimum allowed order total is 0.50 to use this payment method.', 'woocommerce' );
throw new Simplify_ApiException( $error_msg );
}
if ( empty( $cart_token ) ) {
$error_msg = __( 'Please make sure your card details have been entered correctly and that your browser supports JavaScript.', 'woocommerce' );
if ( 'yes' == $this->sandbox ) {
$error_msg .= ' ' . __( 'Developers: Please make sure that you are including jQuery and there are no JavaScript errors on the page.', 'woocommerce' );
}
throw new Simplify_ApiException( $error_msg );
}
// Create customer
$customer = Simplify_Customer::createCustomer(
array(
'token' => $cart_token,
'email' => $order->get_billing_email(),
'name' => trim( $order->get_formatted_billing_full_name() ),
'reference' => $order->get_id(),
)
);
if ( is_object( $customer ) && '' != $customer->id ) {
$customer_id = wc_clean( $customer->id );
// Store the customer ID in the order
update_post_meta( $order->get_id(), '_simplify_customer_id', $customer_id );
} else {
$error_msg = __( 'Error creating user in Simplify Commerce.', 'woocommerce' );
throw new Simplify_ApiException( $error_msg );
}
// Reduce stock levels
wc_reduce_stock_levels( $order->get_id() );
// Remove cart
WC()->cart->empty_cart();
// Is pre ordered!
WC_Pre_Orders_Order::mark_order_as_pre_ordered( $order );
// Return thank you page redirect
return array(
'result' => 'success',
'redirect' => $this->get_return_url( $order ),
);
} catch ( Simplify_ApiException $e ) {
if ( $e instanceof Simplify_BadRequestException && $e->hasFieldErrors() && $e->getFieldErrors() ) {
foreach ( $e->getFieldErrors() as $error ) {
wc_add_notice( $error->getFieldName() . ': "' . $error->getMessage() . '" (' . $error->getErrorCode() . ')', 'error' );
}
} else {
wc_add_notice( $e->getMessage(), 'error' );
}
return array(
'result' => 'fail',
'redirect' => '',
);
}
} else {
return parent::process_standard_payments( $order, $cart_token );
}
}
/**
* Process the payment.
*
* @param int $order_id
* @return array
*/
public function process_payment( $order_id ) {
$cart_token = isset( $_POST['simplify_token'] ) ? wc_clean( $_POST['simplify_token'] ) : '';
$order = wc_get_order( $order_id );
// Processing subscription
if ( 'standard' == $this->mode && ( $this->order_contains_subscription( $order->get_id() ) || ( function_exists( 'wcs_is_subscription' ) && wcs_is_subscription( $order_id ) ) ) ) {
return $this->process_subscription( $order, $cart_token );
} elseif ( 'standard' == $this->mode && $this->order_contains_pre_order( $order->get_id() ) ) {
// Processing pre-order.
return $this->process_pre_order( $order, $cart_token );
} else {
// Processing regular product.
return parent::process_payment( $order_id );
}
}
/**
* process_subscription_payment function.
*
* @param WC_order $order
* @param int $amount (default: 0)
* @uses Simplify_BadRequestException
* @return bool|WP_Error
*/
public function process_subscription_payment( $order, $amount = 0 ) {
if ( 0 == $amount ) {
// Payment complete
$order->payment_complete();
return true;
}
if ( $amount * 100 < 50 ) {
return new WP_Error( 'simplify_error', __( 'Sorry, the minimum allowed order total is 0.50 to use this payment method.', 'woocommerce' ) );
}
$customer_id = get_post_meta( $order->get_id(), '_simplify_customer_id', true );
if ( ! $customer_id ) {
return new WP_Error( 'simplify_error', __( 'Customer not found.', 'woocommerce' ) );
}
try {
// Charge the customer
$payment = Simplify_Payment::createPayment(
array(
'amount' => $amount * 100, // In cents.
'customer' => $customer_id,
'description' => sprintf( __( '%1$s - Order #%2$s', 'woocommerce' ), esc_html( get_bloginfo( 'name', 'display' ) ), $order->get_order_number() ),
'currency' => strtoupper( get_woocommerce_currency() ),
'reference' => $order->get_id(),
)
);
} catch ( Exception $e ) {
$error_message = $e->getMessage();
if ( $e instanceof Simplify_BadRequestException && $e->hasFieldErrors() && $e->getFieldErrors() ) {
$error_message = '';
foreach ( $e->getFieldErrors() as $error ) {
$error_message .= ' ' . $error->getFieldName() . ': "' . $error->getMessage() . '" (' . $error->getErrorCode() . ')';
}
}
$order->add_order_note( sprintf( __( 'Simplify payment error: %s.', 'woocommerce' ), $error_message ) );
return new WP_Error( 'simplify_payment_declined', $e->getMessage(), array( 'status' => $e->getCode() ) );
}
if ( 'APPROVED' == $payment->paymentStatus ) {
// Payment complete
$order->payment_complete( $payment->id );
// Add order note
$order->add_order_note( sprintf( __( 'Simplify payment approved (ID: %1$s, Auth Code: %2$s)', 'woocommerce' ), $payment->id, $payment->authCode ) );
return true;
} else {
$order->add_order_note( __( 'Simplify payment declined', 'woocommerce' ) );
return new WP_Error( 'simplify_payment_declined', __( 'Payment was declined - please try another card.', 'woocommerce' ) );
}
}
/**
* scheduled_subscription_payment function.
*
* @param float $amount_to_charge The amount to charge.
* @param WC_Order $renewal_order A WC_Order object created to record the renewal payment.
*/
public function scheduled_subscription_payment( $amount_to_charge, $renewal_order ) {
$result = $this->process_subscription_payment( $renewal_order, $amount_to_charge );
if ( is_wp_error( $result ) ) {
$renewal_order->update_status( 'failed', sprintf( __( 'Simplify Transaction Failed (%s)', 'woocommerce' ), $result->get_error_message() ) );
}
}
/**
* Update the customer_id for a subscription after using Simplify to complete a payment to make up for.
* an automatic renewal payment which previously failed.
*
* @param WC_Subscription $subscription The subscription for which the failing payment method relates.
* @param WC_Order $renewal_order The order which recorded the successful payment (to make up for the failed automatic payment).
*/
public function update_failing_payment_method( $subscription, $renewal_order ) {
update_post_meta( $subscription->id, '_simplify_customer_id', get_post_meta( $renewal_order->get_id(), '_simplify_customer_id', true ) );
}
/**
* Include the payment meta data required to process automatic recurring payments so that store managers can.
* manually set up automatic recurring payments for a customer via the Edit Subscription screen in Subscriptions v2.0+.
*
* @since 2.4
* @param array $payment_meta associative array of meta data required for automatic payments
* @param WC_Subscription $subscription An instance of a subscription object
* @return array
*/
public function add_subscription_payment_meta( $payment_meta, $subscription ) {
$payment_meta[ $this->id ] = array(
'post_meta' => array(
'_simplify_customer_id' => array(
'value' => get_post_meta( $subscription->id, '_simplify_customer_id', true ),
'label' => 'Simplify Customer ID',
),
),
);
return $payment_meta;
}
/**
* Validate the payment meta data required to process automatic recurring payments so that store managers can.
* manually set up automatic recurring payments for a customer via the Edit Subscription screen in Subscriptions 2.0+.
*
* @since 2.4
* @param string $payment_method_id The ID of the payment method to validate
* @param array $payment_meta associative array of meta data required for automatic payments
* @throws Exception
*/
public function validate_subscription_payment_meta( $payment_method_id, $payment_meta ) {
if ( $this->id === $payment_method_id ) {
if ( ! isset( $payment_meta['post_meta']['_simplify_customer_id']['value'] ) || empty( $payment_meta['post_meta']['_simplify_customer_id']['value'] ) ) {
throw new Exception( 'A "_simplify_customer_id" value is required.' );
}
}
}
/**
* Don't transfer customer meta to resubscribe orders.
*
* @access public
* @param int $resubscribe_order The order created for the customer to resubscribe to the old expired/cancelled subscription
* @return void
*/
public function delete_resubscribe_meta( $resubscribe_order ) {
delete_post_meta( $resubscribe_order->get_id(), '_simplify_customer_id' );
}
/**
* Process a pre-order payment when the pre-order is released.
*
* @param WC_Order $order
* @return WP_Error|null
*/
public function process_pre_order_release_payment( $order ) {
try {
$order_items = $order->get_items();
$order_item = array_shift( $order_items );
/* translators: 1: site name 2: product name 3: order number */
$pre_order_name = sprintf(
__( '%1$s - Pre-order for "%2$s" (Order #%3$s)', 'woocommerce' ),
esc_html( get_bloginfo( 'name', 'display' ) ),
$order_item['name'],
$order->get_order_number()
);
$customer_id = get_post_meta( $order->get_id(), '_simplify_customer_id', true );
if ( ! $customer_id ) {
return new WP_Error( 'simplify_error', __( 'Customer not found.', 'woocommerce' ) );
}
// Charge the customer
$payment = Simplify_Payment::createPayment(
array(
'amount' => $order->get_total() * 100, // In cents.
'customer' => $customer_id,
'description' => trim( substr( $pre_order_name, 0, 1024 ) ),
'currency' => strtoupper( get_woocommerce_currency() ),
'reference' => $order->get_id(),
)
);
if ( 'APPROVED' == $payment->paymentStatus ) {
// Payment complete
$order->payment_complete( $payment->id );
// Add order note
$order->add_order_note( sprintf( __( 'Simplify payment approved (ID: %1$s, Auth Code: %2$s)', 'woocommerce' ), $payment->id, $payment->authCode ) );
} else {
return new WP_Error( 'simplify_payment_declined', __( 'Payment was declined - the customer need to try another card.', 'woocommerce' ) );
}
} catch ( Exception $e ) {
$order_note = sprintf( __( 'Simplify Transaction Failed (%s)', 'woocommerce' ), $e->getMessage() );
// Mark order as failed if not already set,
// otherwise, make sure we add the order note so we can detect when someone fails to check out multiple times
if ( 'failed' != $order->get_status() ) {
$order->update_status( 'failed', $order_note );
} else {
$order->add_order_note( $order_note );
}
}
}
/**
* Return handler for Hosted Payments.
*/
public function return_handler() {
if ( ! isset( $_REQUEST['cardToken'] ) ) {
parent::return_handler();
}
@ob_clean();
header( 'HTTP/1.1 200 OK' );
$redirect_url = wc_get_page_permalink( 'cart' );
if ( isset( $_REQUEST['reference'] ) && isset( $_REQUEST['amount'] ) ) {
$cart_token = $_REQUEST['cardToken'];
$amount = absint( $_REQUEST['amount'] );
$order_id = absint( $_REQUEST['reference'] );
$order = wc_get_order( $order_id );
$order_total = absint( $order->get_total() * 100 );
if ( $amount === $order_total ) {
if ( $this->order_contains_subscription( $order->get_id() ) ) {
$response = $this->process_subscription( $order, $cart_token );
} elseif ( $this->order_contains_pre_order( $order->get_id() ) ) {
$response = $this->process_pre_order( $order, $cart_token );
} else {
$response = parent::process_standard_payments( $order, $cart_token );
}
if ( 'success' == $response['result'] ) {
$redirect_url = $response['redirect'];
} else {
$order->update_status( 'failed', __( 'Payment was declined by Simplify Commerce.', 'woocommerce' ) );
}
wp_redirect( $redirect_url );
exit();
}
}
wp_redirect( $redirect_url );
exit();
}
}

View File

@@ -0,0 +1,777 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Simplify Commerce Gateway.
*
* @class WC_Gateway_Simplify_Commerce
* @extends WC_Payment_Gateway_CC
* @since 2.2.0
* @version 1.0.0
* @package WooCommerce/Classes/Payment
* @author WooThemes
*/
class WC_Gateway_Simplify_Commerce extends WC_Payment_Gateway_CC {
/**
* Constructor.
*/
public function __construct() {
$this->id = 'simplify_commerce';
$this->method_title = __( 'Simplify Commerce', 'woocommerce' );
$this->method_description = __( 'Take payments via Simplify Commerce - uses simplify.js to create card tokens and the Simplify Commerce SDK. Requires SSL when sandbox is disabled.', 'woocommerce' );
$this->new_method_label = __( 'Use a new card', 'woocommerce' );
$this->has_fields = true;
$this->supports = array(
'subscriptions',
'products',
'subscription_cancellation',
'subscription_reactivation',
'subscription_suspension',
'subscription_amount_changes',
'subscription_payment_method_change', // Subscriptions 1.n compatibility
'subscription_payment_method_change_customer',
'subscription_payment_method_change_admin',
'subscription_date_changes',
'multiple_subscriptions',
'default_credit_card_form',
'tokenization',
'refunds',
'pre-orders',
);
$this->view_transaction_url = 'https://www.simplify.com/commerce/app#/payment/%s';
// Load the form fields
$this->init_form_fields();
// Load the settings.
$this->init_settings();
// Get setting values
$this->title = $this->get_option( 'title' );
$this->description = $this->get_option( 'description' );
$this->enabled = $this->get_option( 'enabled' );
$this->mode = $this->get_option( 'mode', 'standard' );
$this->modal_color = $this->get_option( 'modal_color', '#a46497' );
$this->sandbox = $this->get_option( 'sandbox' );
$this->public_key = ( 'no' === $this->sandbox ) ? $this->get_option( 'public_key' ) : $this->get_option( 'sandbox_public_key' );
$this->private_key = ( 'no' === $this->sandbox ) ? $this->get_option( 'private_key' ) : $this->get_option( 'sandbox_private_key' );
$this->init_simplify_sdk();
// Hooks
add_action( 'wp_enqueue_scripts', array( $this, 'payment_scripts' ) );
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
add_action( 'woocommerce_receipt_' . $this->id, array( $this, 'receipt_page' ) );
add_action( 'woocommerce_api_wc_gateway_simplify_commerce', array( $this, 'return_handler' ) );
}
/**
* Init Simplify SDK.
*/
protected function init_simplify_sdk() {
// Include lib
require_once dirname( __FILE__ ) . '/includes/Simplify.php';
Simplify::$publicKey = $this->public_key;
Simplify::$privateKey = $this->private_key;
Simplify::$userAgent = 'WooCommerce/' . WC()->version;
}
/**
* Admin Panel Options.
* - Options for bits like 'title' and availability on a country-by-country basis.
*/
public function admin_options() {
?>
<h3><?php _e( 'Simplify Commerce by MasterCard', 'woocommerce' ); ?></h3>
<?php if ( empty( $this->public_key ) ) : ?>
<div class="simplify-commerce-banner updated">
<img src="<?php echo WC()->plugin_url() . '/includes/gateways/simplify-commerce/assets/images/logo.png'; ?>" />
<p class="main"><strong><?php _e( 'Getting started', 'woocommerce' ); ?></strong></p>
<p><?php _e( 'Simplify Commerce is your merchant account and payment gateway all rolled into one. Choose Simplify Commerce as your WooCommerce payment gateway to get access to your money quickly with a powerful, secure payment engine backed by MasterCard.', 'woocommerce' ); ?></p>
<p><a href="https://www.simplify.com/commerce/partners/woocommerce#/signup" target="_blank" class="button button-primary"><?php _e( 'Sign up for Simplify Commerce', 'woocommerce' ); ?></a> <a href="https://www.simplify.com/commerce/partners/woocommerce#/" target="_blank" class="button"><?php _e( 'Learn more', 'woocommerce' ); ?></a></p>
</div>
<?php else : ?>
<p><?php _e( 'Simplify Commerce is your merchant account and payment gateway all rolled into one. Choose Simplify Commerce as your WooCommerce payment gateway to get access to your money quickly with a powerful, secure payment engine backed by MasterCard.', 'woocommerce' ); ?></p>
<?php endif; ?>
<?php $this->checks(); ?>
<table class="form-table">
<?php $this->generate_settings_html(); ?>
<script type="text/javascript">
jQuery( '#woocommerce_simplify_commerce_sandbox' ).on( 'change', function() {
var sandbox = jQuery( '#woocommerce_simplify_commerce_sandbox_public_key, #woocommerce_simplify_commerce_sandbox_private_key' ).closest( 'tr' ),
production = jQuery( '#woocommerce_simplify_commerce_public_key, #woocommerce_simplify_commerce_private_key' ).closest( 'tr' );
if ( jQuery( this ).is( ':checked' ) ) {
sandbox.show();
production.hide();
} else {
sandbox.hide();
production.show();
}
}).change();
jQuery( '#woocommerce_simplify_commerce_mode' ).on( 'change', function() {
var color = jQuery( '#woocommerce_simplify_commerce_modal_color' ).closest( 'tr' );
if ( 'standard' === jQuery( this ).val() ) {
color.hide();
} else {
color.show();
}
}).change();
</script>
</table>
<?php
}
/**
* Check if SSL is enabled and notify the user.
*/
public function checks() {
if ( 'no' == $this->enabled ) {
return;
}
if ( version_compare( phpversion(), '5.3', '<' ) ) {
// PHP Version
echo '<div class="error"><p>' . sprintf( __( 'Simplify Commerce Error: Simplify commerce requires PHP 5.3 and above. You are using version %s.', 'woocommerce' ), phpversion() ) . '</p></div>';
} elseif ( ! $this->public_key || ! $this->private_key ) {
// Check required fields
echo '<div class="error"><p>' . __( 'Simplify Commerce Error: Please enter your public and private keys', 'woocommerce' ) . '</p></div>';
} elseif ( 'standard' == $this->mode && ! wc_checkout_is_https() ) {
// Show message when using standard mode and no SSL on the checkout page
echo '<div class="error"><p>' . sprintf( __( 'Simplify Commerce is enabled, but the <a href="%s">force SSL option</a> is disabled; your checkout may not be secure! Please enable SSL and ensure your server has a valid SSL certificate - Simplify Commerce will only work in sandbox mode.', 'woocommerce' ), admin_url( 'admin.php?page=wc-settings&tab=checkout' ) ) . '</p></div>';
}
}
/**
* Check if this gateway is enabled.
*
* @return bool
*/
public function is_available() {
if ( 'yes' !== $this->enabled ) {
return false;
}
if ( 'standard' === $this->mode && 'yes' !== $this->sandbox && ! wc_checkout_is_https() ) {
return false;
}
if ( ! $this->public_key || ! $this->private_key ) {
return false;
}
return true;
}
/**
* Initialise Gateway Settings Form Fields.
*/
public function init_form_fields() {
$this->form_fields = array(
'enabled' => array(
'title' => __( 'Enable/Disable', 'woocommerce' ),
'label' => __( 'Enable Simplify Commerce', 'woocommerce' ),
'type' => 'checkbox',
'description' => '',
'default' => 'no',
),
'title' => array(
'title' => __( 'Title', 'woocommerce' ),
'type' => 'text',
'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ),
'default' => __( 'Credit card', 'woocommerce' ),
'desc_tip' => true,
),
'description' => array(
'title' => __( 'Description', 'woocommerce' ),
'type' => 'text',
'description' => __( 'This controls the description which the user sees during checkout.', 'woocommerce' ),
'default' => 'Pay with your credit card via Simplify Commerce by MasterCard.',
'desc_tip' => true,
),
'mode' => array(
'title' => __( 'Payment mode', 'woocommerce' ),
'label' => __( 'Enable Hosted Payments', 'woocommerce' ),
'type' => 'select',
'description' => sprintf( __( 'Standard will display the credit card fields on your store (SSL required). %1$s Hosted Payments will display a Simplify Commerce modal dialog on your store (if SSL) or will redirect the customer to Simplify Commerce hosted page (if not SSL). %1$s Note: Hosted Payments need a new API Key pair with the hosted payments flag selected. %2$sFor more details check the Simplify Commerce docs%3$s.', 'woocommerce' ), '<br />', '<a href="https://simplify.desk.com/customer/portal/articles/1792405-how-do-i-enable-hosted-payments" target="_blank">', '</a>' ),
'default' => 'standard',
'options' => array(
'standard' => __( 'Standard', 'woocommerce' ),
'hosted' => __( 'Hosted Payments', 'woocommerce' ),
),
),
'modal_color' => array(
'title' => __( 'Modal color', 'woocommerce' ),
'type' => 'color',
'description' => __( 'Set the color of the buttons and titles on the modal dialog.', 'woocommerce' ),
'default' => '#a46497',
'desc_tip' => true,
),
'sandbox' => array(
'title' => __( 'Sandbox', 'woocommerce' ),
'label' => __( 'Enable sandbox mode', 'woocommerce' ),
'type' => 'checkbox',
'description' => __( 'Place the payment gateway in sandbox mode using sandbox API keys (real payments will not be taken).', 'woocommerce' ),
'default' => 'yes',
),
'sandbox_public_key' => array(
'title' => __( 'Sandbox public key', 'woocommerce' ),
'type' => 'text',
'description' => __( 'Get your API keys from your Simplify account: Settings > API Keys.', 'woocommerce' ),
'default' => '',
'desc_tip' => true,
),
'sandbox_private_key' => array(
'title' => __( 'Sandbox private key', 'woocommerce' ),
'type' => 'text',
'description' => __( 'Get your API keys from your Simplify account: Settings > API Keys.', 'woocommerce' ),
'default' => '',
'desc_tip' => true,
),
'public_key' => array(
'title' => __( 'Public key', 'woocommerce' ),
'type' => 'text',
'description' => __( 'Get your API keys from your Simplify account: Settings > API Keys.', 'woocommerce' ),
'default' => '',
'desc_tip' => true,
),
'private_key' => array(
'title' => __( 'Private key', 'woocommerce' ),
'type' => 'text',
'description' => __( 'Get your API keys from your Simplify account: Settings > API Keys.', 'woocommerce' ),
'default' => '',
'desc_tip' => true,
),
);
}
/**
* Payment form on checkout page.
*/
public function payment_fields() {
$description = $this->get_description();
if ( 'yes' == $this->sandbox ) {
$description .= ' ' . sprintf( __( 'TEST MODE ENABLED. Use a test card: %s', 'woocommerce' ), '<a href="https://www.simplify.com/commerce/docs/tutorial/index#testing">https://www.simplify.com/commerce/docs/tutorial/index#testing</a>' );
}
if ( $description ) {
echo wpautop( wptexturize( trim( $description ) ) );
}
if ( 'standard' == $this->mode ) {
parent::payment_fields();
}
}
/**
* Outputs scripts used for simplify payment.
*/
public function payment_scripts() {
$load_scripts = false;
if ( is_checkout() ) {
$load_scripts = true;
}
if ( $this->is_available() ) {
$load_scripts = true;
}
if ( false === $load_scripts ) {
return;
}
wp_enqueue_script( 'simplify-commerce', 'https://www.simplify.com/commerce/v1/simplify.js', array( 'jquery' ), WC_VERSION, true );
wp_enqueue_script( 'wc-simplify-commerce', WC()->plugin_url() . '/includes/gateways/simplify-commerce/assets/js/simplify-commerce.js', array( 'simplify-commerce', 'wc-credit-card-form' ), WC_VERSION, true );
wp_localize_script(
'wc-simplify-commerce', 'Simplify_commerce_params', array(
'key' => $this->public_key,
'card.number' => __( 'Card number', 'woocommerce' ),
'card.expMonth' => __( 'Expiry month', 'woocommerce' ),
'card.expYear' => __( 'Expiry year', 'woocommerce' ),
'is_invalid' => __( 'is invalid', 'woocommerce' ),
'mode' => $this->mode,
'is_ssl' => is_ssl(),
)
);
}
public function add_payment_method() {
if ( empty( $_POST['simplify_token'] ) ) {
wc_add_notice( __( 'There was a problem adding this card.', 'woocommerce' ), 'error' );
return;
}
$cart_token = wc_clean( $_POST['simplify_token'] );
$customer_token = $this->get_users_token();
$current_user = wp_get_current_user();
$customer_info = array(
'email' => $current_user->user_email,
'name' => $current_user->display_name,
);
$token = $this->save_token( $customer_token, $cart_token, $customer_info );
if ( is_null( $token ) ) {
wc_add_notice( __( 'There was a problem adding this card.', 'woocommerce' ), 'error' );
return;
}
return array(
'result' => 'success',
'redirect' => wc_get_endpoint_url( 'payment-methods' ),
);
}
/**
* Actually saves a customer token to the database.
*
* @param WC_Payment_Token $customer_token Payment Token
* @param string $cart_token CC Token
* @param array $customer_info 'email', 'name'
*
* @return null|WC_Payment_Token|WC_Payment_Token_CC
*/
public function save_token( $customer_token, $cart_token, $customer_info ) {
if ( ! is_null( $customer_token ) ) {
$customer = Simplify_Customer::findCustomer( $customer_token->get_token() );
$updates = array( 'token' => $cart_token );
$customer->setAll( $updates );
$customer->updateCustomer();
$customer = Simplify_Customer::findCustomer( $customer_token->get_token() ); // get updated customer with new set card
$token = $customer_token;
} else {
$customer = Simplify_Customer::createCustomer(
array(
'token' => $cart_token,
'email' => $customer_info['email'],
'name' => $customer_info['name'],
)
);
$token = new WC_Payment_Token_CC();
$token->set_token( $customer->id );
}
// If we were able to create an save our card, save the data on our side too
if ( is_object( $customer ) && '' != $customer->id ) {
$customer_properties = $customer->getProperties();
$card = $customer_properties['card'];
$token->set_gateway_id( $this->id );
$token->set_card_type( strtolower( $card->type ) );
$token->set_last4( $card->last4 );
$expiry_month = ( 1 === strlen( $card->expMonth ) ? '0' . $card->expMonth : $card->expMonth );
$token->set_expiry_month( $expiry_month );
$token->set_expiry_year( '20' . $card->expYear );
if ( is_user_logged_in() ) {
$token->set_user_id( get_current_user_id() );
}
$token->save();
return $token;
}
return null;
}
/**
* Process customer: updating or creating a new customer/saved CC
*
* @param WC_Order $order Order object
* @param WC_Payment_Token $customer_token Payment Token
* @param string $cart_token CC Token
*/
protected function process_customer( $order, $customer_token = null, $cart_token = '' ) {
// Are we saving a new payment method?
if ( is_user_logged_in() && isset( $_POST['wc-simplify_commerce-new-payment-method'] ) && true === (bool) $_POST['wc-simplify_commerce-new-payment-method'] ) {
$customer_info = array(
'email' => $order->get_billing_email(),
'name' => trim( $order->get_formatted_billing_full_name() ),
);
$token = $this->save_token( $customer_token, $cart_token, $customer_info );
if ( ! is_null( $token ) ) {
$order->add_payment_token( $token );
}
}
}
/**
* Process standard payments.
*
* @param WC_Order $order
* @param string $cart_token
* @param string $customer_token
*
* @return array
* @uses Simplify_ApiException
* @uses Simplify_BadRequestException
*/
protected function process_standard_payments( $order, $cart_token = '', $customer_token = '' ) {
try {
if ( empty( $cart_token ) && empty( $customer_token ) ) {
$error_msg = __( 'Please make sure your card details have been entered correctly and that your browser supports JavaScript.', 'woocommerce' );
if ( 'yes' == $this->sandbox ) {
$error_msg .= ' ' . __( 'Developers: Please make sure that you are including jQuery and there are no JavaScript errors on the page.', 'woocommerce' );
}
throw new Simplify_ApiException( $error_msg );
}
// We need to figure out if we want to charge the card token (new unsaved token, no customer, etc)
// or the customer token (just saved method, previously saved method)
$pass_tokens = array();
if ( ! empty( $cart_token ) ) {
$pass_tokens['token'] = $cart_token;
}
if ( ! empty( $customer_token ) ) {
$pass_tokens['customer'] = $customer_token;
// Use the customer token only, since we already saved the (one time use) card token to the customer
if ( isset( $_POST['wc-simplify_commerce-new-payment-method'] ) && true === (bool) $_POST['wc-simplify_commerce-new-payment-method'] ) {
unset( $pass_tokens['token'] );
}
}
// Did we create an account and save a payment method? We might need to use the customer token instead of the card token
if ( isset( $_POST['createaccount'] ) && true === (bool) $_POST['createaccount'] && empty( $customer_token ) ) {
$user_token = $this->get_users_token();
if ( ! is_null( $user_token ) ) {
$pass_tokens['customer'] = $user_token->get_token();
unset( $pass_tokens['token'] );
}
}
$payment_response = $this->do_payment( $order, $order->get_total(), $pass_tokens );
if ( is_wp_error( $payment_response ) ) {
throw new Simplify_ApiException( $payment_response->get_error_message() );
} else {
// Remove cart
WC()->cart->empty_cart();
// Return thank you page redirect
return array(
'result' => 'success',
'redirect' => $this->get_return_url( $order ),
);
}
} catch ( Simplify_ApiException $e ) {
if ( $e instanceof Simplify_BadRequestException && $e->hasFieldErrors() && $e->getFieldErrors() ) {
foreach ( $e->getFieldErrors() as $error ) {
wc_add_notice( $error->getFieldName() . ': "' . $error->getMessage() . '" (' . $error->getErrorCode() . ')', 'error' );
}
} else {
wc_add_notice( $e->getMessage(), 'error' );
}
return array(
'result' => 'fail',
'redirect' => '',
);
}
}
/**
* do payment function.
*
* @param WC_order $order
* @param int $amount (default: 0)
* @param array $token
*
* @return bool|WP_Error
* @uses Simplify_BadRequestException
*/
public function do_payment( $order, $amount = 0, $token = array() ) {
if ( $amount * 100 < 50 ) {
return new WP_Error( 'simplify_error', __( 'Sorry, the minimum allowed order total is 0.50 to use this payment method.', 'woocommerce' ) );
}
try {
// Charge the customer
$data = array(
'amount' => $amount * 100, // In cents.
'description' => sprintf( __( '%1$s - Order #%2$s', 'woocommerce' ), esc_html( get_bloginfo( 'name', 'display' ) ), $order->get_order_number() ),
'currency' => strtoupper( get_woocommerce_currency() ),
'reference' => $order->get_id(),
);
$data = array_merge( $data, $token );
$payment = Simplify_Payment::createPayment( $data );
} catch ( Exception $e ) {
$error_message = $e->getMessage();
if ( $e instanceof Simplify_BadRequestException && $e->hasFieldErrors() && $e->getFieldErrors() ) {
$error_message = '';
foreach ( $e->getFieldErrors() as $error ) {
$error_message .= ' ' . $error->getFieldName() . ': "' . $error->getMessage() . '" (' . $error->getErrorCode() . ')';
}
}
$order->add_order_note( sprintf( __( 'Simplify payment error: %s.', 'woocommerce' ), $error_message ) );
return new WP_Error( 'simplify_payment_declined', $e->getMessage(), array( 'status' => $e->getCode() ) );
}
if ( 'APPROVED' == $payment->paymentStatus ) {
// Payment complete
$order->payment_complete( $payment->id );
// Add order note
$order->add_order_note( sprintf( __( 'Simplify payment approved (ID: %1$s, Auth Code: %2$s)', 'woocommerce' ), $payment->id, $payment->authCode ) );
return true;
} else {
$order->add_order_note( __( 'Simplify payment declined', 'woocommerce' ) );
return new WP_Error( 'simplify_payment_declined', __( 'Payment was declined - please try another card.', 'woocommerce' ) );
}
}
/**
* Process standard payments.
*
* @param WC_Order $order
* @return array
*/
protected function process_hosted_payments( $order ) {
return array(
'result' => 'success',
'redirect' => $order->get_checkout_payment_url( true ),
);
}
protected function get_users_token() {
$customer_token = null;
if ( is_user_logged_in() ) {
$tokens = WC_Payment_Tokens::get_customer_tokens( get_current_user_id() );
foreach ( $tokens as $token ) {
if ( $token->get_gateway_id() === $this->id ) {
$customer_token = $token;
break;
}
}
}
return $customer_token;
}
/**
* Process the payment.
*
* @param int $order_id
*
* @return array|void
*/
public function process_payment( $order_id ) {
$order = wc_get_order( $order_id );
// Payment/CC form is hosted on Simplify
if ( 'hosted' === $this->mode ) {
return $this->process_hosted_payments( $order );
}
// New CC info was entered
if ( isset( $_POST['simplify_token'] ) ) {
$cart_token = wc_clean( $_POST['simplify_token'] );
$customer_token = $this->get_users_token();
$customer_token_value = ( ! is_null( $customer_token ) ? $customer_token->get_token() : '' );
$this->process_customer( $order, $customer_token, $cart_token );
return $this->process_standard_payments( $order, $cart_token, $customer_token_value );
}
// Possibly Create (or update) customer/save payment token, use an existing token, and then process the payment
if ( isset( $_POST['wc-simplify_commerce-payment-token'] ) && 'new' !== $_POST['wc-simplify_commerce-payment-token'] ) {
$token_id = wc_clean( $_POST['wc-simplify_commerce-payment-token'] );
$token = WC_Payment_Tokens::get( $token_id );
if ( $token->get_user_id() !== get_current_user_id() ) {
wc_add_notice( __( 'Please make sure your card details have been entered correctly and that your browser supports JavaScript.', 'woocommerce' ), 'error' );
return;
}
$this->process_customer( $order, $token );
return $this->process_standard_payments( $order, '', $token->get_token() );
}
}
/**
* Hosted payment args.
*
* @param WC_Order $order
*
* @return array
*/
protected function get_hosted_payments_args( $order ) {
$args = apply_filters(
'woocommerce_simplify_commerce_hosted_args', array(
'sc-key' => $this->public_key,
'amount' => $order->get_total() * 100,
'reference' => $order->get_id(),
'name' => esc_html( get_bloginfo( 'name', 'display' ) ),
'description' => sprintf( __( 'Order #%s', 'woocommerce' ), $order->get_order_number() ),
'receipt' => 'false',
'color' => $this->modal_color,
'redirect-url' => WC()->api_request_url( 'WC_Gateway_Simplify_Commerce' ),
'address' => $order->get_billing_address_1() . ' ' . $order->get_billing_address_2(),
'address-city' => $order->get_billing_city(),
'address-state' => $order->get_billing_state(),
'address-zip' => $order->get_billing_postcode(),
'address-country' => $order->get_billing_country(),
'operation' => 'create.token',
), $order->get_id()
);
return $args;
}
/**
* Receipt page.
*
* @param int $order_id
*/
public function receipt_page( $order_id ) {
$order = wc_get_order( $order_id );
echo '<p>' . __( 'Thank you for your order, please click the button below to pay with credit card using Simplify Commerce by MasterCard.', 'woocommerce' ) . '</p>';
$args = $this->get_hosted_payments_args( $order );
$button_args = array();
foreach ( $args as $key => $value ) {
$button_args[] = 'data-' . esc_attr( $key ) . '="' . esc_attr( $value ) . '"';
}
echo '<script type="text/javascript" src="https://www.simplify.com/commerce/simplify.pay.js"></script>
<button class="button alt" id="simplify-payment-button" ' . implode( ' ', $button_args ) . '>' . __( 'Pay now', 'woocommerce' ) . '</button> <a class="button cancel" href="' . esc_url( $order->get_cancel_order_url() ) . '">' . __( 'Cancel order &amp; restore cart', 'woocommerce' ) . '</a>
';
}
/**
* Return handler for Hosted Payments.
*/
public function return_handler() {
@ob_clean();
header( 'HTTP/1.1 200 OK' );
if ( isset( $_REQUEST['reference'] ) && isset( $_REQUEST['paymentId'] ) && isset( $_REQUEST['signature'] ) ) {
$signature = strtoupper( md5( $_REQUEST['amount'] . $_REQUEST['reference'] . $_REQUEST['paymentId'] . $_REQUEST['paymentDate'] . $_REQUEST['paymentStatus'] . $this->private_key ) );
$order_id = absint( $_REQUEST['reference'] );
$order = wc_get_order( $order_id );
if ( hash_equals( $signature, $_REQUEST['signature'] ) ) {
$order_complete = $this->process_order_status( $order, $_REQUEST['paymentId'], $_REQUEST['paymentStatus'], $_REQUEST['paymentDate'] );
if ( ! $order_complete ) {
$order->update_status( 'failed', __( 'Payment was declined by Simplify Commerce.', 'woocommerce' ) );
}
wp_redirect( $this->get_return_url( $order ) );
exit();
}
}
wp_redirect( wc_get_page_permalink( 'cart' ) );
exit();
}
/**
* Process the order status.
*
* @param WC_Order $order
* @param string $payment_id
* @param string $status
* @param string $auth_code
*
* @return bool
*/
public function process_order_status( $order, $payment_id, $status, $auth_code ) {
if ( 'APPROVED' == $status ) {
// Payment complete
$order->payment_complete( $payment_id );
// Add order note
$order->add_order_note( sprintf( __( 'Simplify payment approved (ID: %1$s, Auth Code: %2$s)', 'woocommerce' ), $payment_id, $auth_code ) );
// Remove cart
WC()->cart->empty_cart();
return true;
}
return false;
}
/**
* Process refunds.
* WooCommerce 2.2 or later.
*
* @param int $order_id
* @param float $amount
* @param string $reason
* @uses Simplify_ApiException
* @uses Simplify_BadRequestException
* @return bool|WP_Error
*/
public function process_refund( $order_id, $amount = null, $reason = '' ) {
try {
$payment_id = get_post_meta( $order_id, '_transaction_id', true );
$refund = Simplify_Refund::createRefund(
array(
'amount' => $amount * 100, // In cents.
'payment' => $payment_id,
'reason' => $reason,
'reference' => $order_id,
)
);
if ( 'APPROVED' == $refund->paymentStatus ) {
return true;
} else {
throw new Simplify_ApiException( __( 'Refund was declined.', 'woocommerce' ) );
}
} catch ( Simplify_ApiException $e ) {
if ( $e instanceof Simplify_BadRequestException && $e->hasFieldErrors() && $e->getFieldErrors() ) {
foreach ( $e->getFieldErrors() as $error ) {
return new WP_Error( 'simplify_refund_error', $error->getFieldName() . ': "' . $error->getMessage() . '" (' . $error->getErrorCode() . ')' );
}
} else {
return new WP_Error( 'simplify_refund_error', $e->getMessage() );
}
}
return false;
}
/**
* Get gateway icon.
*
* @access public
* @return string
*/
public function get_icon() {
$icon = '<img src="' . WC_HTTPS::force_https_url( WC()->plugin_url() . '/assets/images/icons/credit-cards/visa.svg' ) . '" alt="Visa" width="32" />';
$icon .= '<img src="' . WC_HTTPS::force_https_url( WC()->plugin_url() . '/assets/images/icons/credit-cards/mastercard.svg' ) . '" alt="MasterCard" width="32" />';
$icon .= '<img src="' . WC_HTTPS::force_https_url( WC()->plugin_url() . '/assets/images/icons/credit-cards/discover.svg' ) . '" alt="Discover" width="32" />';
$icon .= '<img src="' . WC_HTTPS::force_https_url( WC()->plugin_url() . '/assets/images/icons/credit-cards/amex.svg' ) . '" alt="Amex" width="32" />';
$icon .= '<img src="' . WC_HTTPS::force_https_url( WC()->plugin_url() . '/assets/images/icons/credit-cards/jcb.svg' ) . '" alt="JCB" width="32" />';
return apply_filters( 'woocommerce_gateway_icon', $icon, $this->id );
}
}

View File

@@ -0,0 +1,88 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/*
* Copyright (c) 2013 - 2015 MasterCard International Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* Neither the name of the MasterCard International Incorporated nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
// @codingStandardsIgnoreFile
require_once(dirname(__FILE__) . '/Simplify/Constants.php');
class Simplify
{
/**
* @var string $publicKey public API key used to authenticate requests.
*/
public static $publicKey;
/**
* @var string $privateKey private API key used to authenticate requests.
*/
public static $privateKey;
/**
* @var string $apiBaseLiveUrl URL of the live API endpoint
*/
public static $apiBaseLiveUrl = Simplify_Constants::API_BASE_LIVE_URL;
/**
* @var string $apiBaseSandboxUrl URL of the sandbox API endpoint
*/
public static $apiBaseSandboxUrl = Simplify_Constants::API_BASE_SANDBOX_URL;
/**
* @var string $userAgent User-agent string send with requests.
*/
public static $userAgent = null;
}
require_once(dirname(__FILE__) . '/Simplify/Object.php');
require_once(dirname(__FILE__) . '/Simplify/AccessToken.php');
require_once(dirname(__FILE__) . '/Simplify/Authentication.php');
require_once(dirname(__FILE__) . '/Simplify/PaymentsApi.php');
require_once(dirname(__FILE__) . '/Simplify/Exceptions.php');
require_once(dirname(__FILE__) . '/Simplify/Http.php');
require_once(dirname(__FILE__) . '/Simplify/ResourceList.php');
require_once(dirname(__FILE__) . '/Simplify/Authorization.php');
require_once(dirname(__FILE__) . '/Simplify/CardToken.php');
require_once(dirname(__FILE__) . '/Simplify/Chargeback.php');
require_once(dirname(__FILE__) . '/Simplify/Coupon.php');
require_once(dirname(__FILE__) . '/Simplify/Customer.php');
require_once(dirname(__FILE__) . '/Simplify/Deposit.php');
require_once(dirname(__FILE__) . '/Simplify/Event.php');
require_once(dirname(__FILE__) . '/Simplify/FraudCheck.php');
require_once(dirname(__FILE__) . '/Simplify/Invoice.php');
require_once(dirname(__FILE__) . '/Simplify/InvoiceItem.php');
require_once(dirname(__FILE__) . '/Simplify/Tax.php');
require_once(dirname(__FILE__) . '/Simplify/Payment.php');
require_once(dirname(__FILE__) . '/Simplify/Plan.php');
require_once(dirname(__FILE__) . '/Simplify/Refund.php');
require_once(dirname(__FILE__) . '/Simplify/Subscription.php');
require_once(dirname(__FILE__) . '/Simplify/TransactionReview.php');
require_once(dirname(__FILE__) . '/Simplify/Webhook.php');

View File

@@ -0,0 +1,127 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/*
* Copyright (c) 2013 - 2015 MasterCard International Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* Neither the name of the MasterCard International Incorporated nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* AccessToken - used to manage OAuth access tokens
*/
class Simplify_AccessToken extends Simplify_Object {
public function __construct($hash) {
$this->setAll($hash);
}
/**
* Creates an OAuth access token
* @param $code - the authorisation code returned from the GET on /oauth/authorize
* @param $redirect_uri = this must be the redirect_uri set in the apps configuration
* @param $authentication - Authentication information to access the API. If not value is passed the global key Simplify::$publicKey and Simplify::$privateKey are used
* @return Simplify_AccessToken
*/
public static function create($code, $redirect_uri, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 3);
$props = 'code='.$code.'&redirect_uri='.$redirect_uri.'&grant_type=authorization_code';
$resp = Simplify_AccessToken::sendRequest($props, "token", $authentication);
return new Simplify_AccessToken($resp);
}
/**
* Refreshes the current token. The access_token and refresh_token values will be updated.
* @param $authentication - Authentication information to access the API. If not value is passed the global key Simplify::$publicKey and Simplify::$privateKey are used
* @return Simplify_AccessToken
* @throws InvalidArgumentException
*/
public function refresh($authentication = null) {
$args = func_get_args();
$refresh_token = $this->refresh_token;
if (empty($refresh_token)){
throw new InvalidArgumentException('Cannot refresh access token; refresh token is invalid');
}
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 1);
$props = 'refresh_token='.$refresh_token.'&grant_type=refresh_token';
$resp = Simplify_AccessToken::sendRequest($props, "token", $authentication);
$this->setAll($resp);
return $this;
}
/**
* <p>Revokes a token from further use.
* @param $authentication - Authentication information to access the API. If not value is passed the global key Simplify::$publicKey and Simplify::$privateKey are used
* @return Simplify_AccessToken
* @throws InvalidArgumentException
*/
public function revoke($authentication = null) {
$args = func_get_args();
$access_token = $this->access_token;
if (empty($access_token)){
throw new InvalidArgumentException('Cannot revoke access token; access token is invalid');
}
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$props = 'token='.$access_token.'';
Simplify_AccessToken::sendRequest($props, "revoke", $authentication);
$this->access_token = null;
$this->refresh_token = null;
$this->redirect_uri = null;
return $this;
}
private static function sendRequest($props, $context, $authentication){
$url = Simplify_Constants::OAUTH_BASE_URL.'/'.$context;
$http = new Simplify_HTTP();
$resp = $http->oauthRequest($url, $props, $authentication);
return $resp;
}
/**
* @ignore
*/
static public function getClazz() {
return "AccessToken";
}
}

View File

@@ -0,0 +1,74 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/*
* Copyright (c) 2013 - 2015 MasterCard International Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* Neither the name of the MasterCard International Incorporated nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* Simplify_Authentication - encapsulates the credentials needed to make a request to the Simplify API.
*
* @var $publicKey - this is your API public key
* @var $privateKey - this is your API private key
* @var $accessToken - Oauth access token that is needed to make API requests on behalf of another user
*/
class Simplify_Authentication {
public $privateKey;
public $publicKey;
public $accessToken;
function __construct() {
$args = func_get_args();
switch( func_num_args() ) {
case 1:
self::__construct1( $args[0] );
break;
case 2:
self::__construct2( $args[0], $args[1] );
break;
case 3:
self::__construct3( $args[0], $args[1], $args[2] );
}
}
function __construct1($accessToken) {
$this->accessToken = $accessToken;
}
function __construct2($publicKey, $privateKey) {
$this->publicKey = $publicKey;
$this->privateKey = $privateKey;
}
function __construct3($publicKey, $privateKey, $accessToken) {
$this->publicKey = $publicKey;
$this->privateKey = $privateKey;
$this->accessToken = $accessToken;
}
}

View File

@@ -0,0 +1,142 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/*
* Copyright (c) 2013 - 2015 MasterCard International Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* Neither the name of the MasterCard International Incorporated nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
class Simplify_Authorization extends Simplify_Object {
/**
* Creates an Simplify_Authorization object
* @param array $hash a map of parameters; valid keys are:<dl style="padding-left:10px;">
* <dt><tt>amount</tt></dt> <dd>Amount of the payment (in the smallest unit of your currency). Example: 100 = $1.00USD <strong>required </strong></dd>
* <dt><tt>card.addressCity</tt></dt> <dd>City of the cardholder. [max length: 50, min length: 2] </dd>
* <dt><tt>card.addressCountry</tt></dt> <dd>Country code (ISO-3166-1-alpha-2 code) of residence of the cardholder. [max length: 2, min length: 2] </dd>
* <dt><tt>card.addressLine1</tt></dt> <dd>Address of the cardholder. [max length: 255] </dd>
* <dt><tt>card.addressLine2</tt></dt> <dd>Address of the cardholder if needed. [max length: 255] </dd>
* <dt><tt>card.addressState</tt></dt> <dd>State of residence of the cardholder. For the US, this is a 2-digit USPS code. [max length: 255, min length: 2] </dd>
* <dt><tt>card.addressZip</tt></dt> <dd>Postal code of the cardholder. The postal code size is between 5 and 9 characters in length and only contains numbers or letters. [max length: 9, min length: 3] </dd>
* <dt><tt>card.cvc</tt></dt> <dd>CVC security code of the card. This is the code on the back of the card. Example: 123 </dd>
* <dt><tt>card.expMonth</tt></dt> <dd>Expiration month of the card. Format is MM. Example: January = 01 [min value: 1, max value: 12] <strong>required </strong></dd>
* <dt><tt>card.expYear</tt></dt> <dd>Expiration year of the card. Format is YY. Example: 2013 = 13 [min value: 0, max value: 99] <strong>required </strong></dd>
* <dt><tt>card.name</tt></dt> <dd>Name as it appears on the card. [max length: 50, min length: 2] </dd>
* <dt><tt>card.number</tt></dt> <dd>Card number as it appears on the card. [max length: 19, min length: 13] <strong>required </strong></dd>
* <dt><tt>currency</tt></dt> <dd>Currency code (ISO-4217) for the transaction. Must match the currency associated with your account. [default: USD] <strong>required </strong></dd>
* <dt><tt>customer</tt></dt> <dd>ID of customer. If specified, card on file of customer will be used. </dd>
* <dt><tt>description</tt></dt> <dd>Free form text field to be used as a description of the payment. This field is echoed back with the payment on any find or list operations. [max length: 1024] </dd>
* <dt><tt>reference</tt></dt> <dd>Custom reference field to be used with outside systems. </dd>
* <dt><tt>replayId</tt></dt> <dd>An identifier that can be sent to uniquely identify a payment request to facilitate retries due to I/O related issues. This identifier must be unique for your account (sandbox or live) across all of your payments. If supplied, we will check for a payment on your account that matches this identifier, and if one is found we will attempt to return an identical response of the original request. [max length: 50, min length: 1] </dd>
* <dt><tt>statementDescription.name</tt></dt> <dd>Merchant name <strong>required </strong></dd>
* <dt><tt>statementDescription.phoneNumber</tt></dt> <dd>Merchant contact phone number. </dd>
* <dt><tt>token</tt></dt> <dd>If specified, card associated with card token will be used. [max length: 255] </dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.<i/>
* @return Authorization a Authorization object.
*/
static public function createAuthorization($hash, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$instance = new Simplify_Authorization();
$instance->setAll($hash);
$object = Simplify_PaymentsApi::createObject($instance, $authentication);
return $object;
}
/**
* Deletes an Simplify_Authorization object.
*
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
*
* @return true
*/
public function deleteAuthorization($authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 1);
$obj = Simplify_PaymentsApi::deleteObject($this, $authentication);
$this->properties = null;
return true;
}
/**
* Retrieve Simplify_Authorization objects.
* @param array criteria a map of parameters; valid keys are:<dl style="padding-left:10px;">
* <dt><tt>filter</tt></dt> <dd>Filters to apply to the list. </dd>
* <dt><tt>max</tt></dt> <dd>Allows up to a max of 50 list items to return. [min value: 0, max value: 50, default: 20] </dd>
* <dt><tt>offset</tt></dt> <dd>Used in pagination of the list. This is the start offset of the page. [min value: 0, default: 0] </dd>
* <dt><tt>sorting</tt></dt> <dd>Allows for ascending or descending sorting of the list. The value maps properties to the sort direction (either <tt>asc</tt> for ascending or <tt>desc</tt> for descending). Sortable properties are: <tt> dateCreated</tt><tt> amount</tt><tt> id</tt><tt> description</tt><tt> paymentDate</tt>.</dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return ResourceList a ResourceList object that holds the list of Authorization objects and the total
* number of Authorization objects available for the given criteria.
* @see ResourceList
*/
static public function listAuthorization($criteria = null, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_Authorization();
$list = Simplify_PaymentsApi::listObject($val, $criteria, $authentication);
return $list;
}
/**
* Retrieve a Simplify_Authorization object from the API
*
* @param string id the id of the Authorization object to retrieve
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return Authorization a Authorization object
*/
static public function findAuthorization($id, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_Authorization();
$val->id = $id;
$obj = Simplify_PaymentsApi::findObject($val, $authentication);
return $obj;
}
/**
* @ignore
*/
public function getClazz() {
return "Authorization";
}
}

View File

@@ -0,0 +1,94 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/*
* Copyright (c) 2013 - 2015 MasterCard International Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* Neither the name of the MasterCard International Incorporated nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
class Simplify_CardToken extends Simplify_Object {
/**
* Creates an Simplify_CardToken object
* @param array $hash a map of parameters; valid keys are:<dl style="padding-left:10px;">
* <dt><tt>callback</tt></dt> <dd>The URL callback for the cardtoken </dd>
* <dt><tt>card.addressCity</tt></dt> <dd>City of the cardholder. [max length: 50, min length: 2] </dd>
* <dt><tt>card.addressCountry</tt></dt> <dd>Country code (ISO-3166-1-alpha-2 code) of residence of the cardholder. [max length: 2, min length: 2] </dd>
* <dt><tt>card.addressLine1</tt></dt> <dd>Address of the cardholder. [max length: 255] </dd>
* <dt><tt>card.addressLine2</tt></dt> <dd>Address of the cardholder if needed. [max length: 255] </dd>
* <dt><tt>card.addressState</tt></dt> <dd>State of residence of the cardholder. For the US, this is a 2-digit USPS code. [max length: 255, min length: 2] </dd>
* <dt><tt>card.addressZip</tt></dt> <dd>Postal code of the cardholder. The postal code size is between 5 and 9 in length and only contain numbers or letters. [max length: 9, min length: 3] </dd>
* <dt><tt>card.cvc</tt></dt> <dd>CVC security code of the card. This is the code on the back of the card. Example: 123 </dd>
* <dt><tt>card.expMonth</tt></dt> <dd>Expiration month of the card. Format is MM. Example: January = 01 [min value: 1, max value: 12] <strong>required </strong></dd>
* <dt><tt>card.expYear</tt></dt> <dd>Expiration year of the card. Format is YY. Example: 2013 = 13 [min value: 0, max value: 99] <strong>required </strong></dd>
* <dt><tt>card.name</tt></dt> <dd>Name as appears on the card. [max length: 50, min length: 2] </dd>
* <dt><tt>card.number</tt></dt> <dd>Card number as it appears on the card. [max length: 19, min length: 13] <strong>required </strong></dd>
* <dt><tt>key</tt></dt> <dd>Key used to create the card token. </dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.<i/>
* @return CardToken a CardToken object.
*/
static public function createCardToken($hash, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$instance = new Simplify_CardToken();
$instance->setAll($hash);
$object = Simplify_PaymentsApi::createObject($instance, $authentication);
return $object;
}
/**
* Retrieve a Simplify_CardToken object from the API
*
* @param string id the id of the CardToken object to retrieve
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return CardToken a CardToken object
*/
static public function findCardToken($id, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_CardToken();
$val->id = $id;
$obj = Simplify_PaymentsApi::findObject($val, $authentication);
return $obj;
}
/**
* @ignore
*/
public function getClazz() {
return "CardToken";
}
}

View File

@@ -0,0 +1,86 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/*
* Copyright (c) 2013 - 2015 MasterCard International Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* Neither the name of the MasterCard International Incorporated nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
class Simplify_Chargeback extends Simplify_Object {
/**
* Retrieve Simplify_Chargeback objects.
* @param array criteria a map of parameters; valid keys are:<dl style="padding-left:10px;">
* <dt><tt>filter</tt></dt> <dd>Filters to apply to the list. </dd>
* <dt><tt>max</tt></dt> <dd>Allows up to a max of 50 list items to return. [min value: 0, max value: 50, default: 20] </dd>
* <dt><tt>offset</tt></dt> <dd>Used in paging of the list. This is the start offset of the page. [min value: 0, default: 0] </dd>
* <dt><tt>sorting</tt></dt> <dd>Allows for ascending or descending sorting of the list. The value maps properties to the sort direction (either <tt>asc</tt> for ascending or <tt>desc</tt> for descending). Sortable properties are: <tt> id</tt><tt> amount</tt><tt> description</tt><tt> dateCreated</tt>.</dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return ResourceList a ResourceList object that holds the list of Chargeback objects and the total
* number of Chargeback objects available for the given criteria.
* @see ResourceList
*/
static public function listChargeback($criteria = null, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_Chargeback();
$list = Simplify_PaymentsApi::listObject($val, $criteria, $authentication);
return $list;
}
/**
* Retrieve a Simplify_Chargeback object from the API
*
* @param string id the id of the Chargeback object to retrieve
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return Chargeback a Chargeback object
*/
static public function findChargeback($id, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_Chargeback();
$val->id = $id;
$obj = Simplify_PaymentsApi::findObject($val, $authentication);
return $obj;
}
/**
* @ignore
*/
public function getClazz() {
return "Chargeback";
}
}

View File

@@ -0,0 +1,58 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/*
* Copyright (c) 2013 - 2015 MasterCard International Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* Neither the name of the MasterCard International Incorporated nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* Constant values.
*/
class Simplify_Constants
{
/**
* @var string VERSION SDK version information.
*/
const VERSION = '1.2.0';
/**
* @var string API_BASE_LIVE_URL URL for the live API endpoint
*/
const API_BASE_LIVE_URL = 'https://api.simplify.com/v1/api';
/**
* @var string API_BASE_SANDBOX_URL URL for the sandbox API endpoint
*/
const API_BASE_SANDBOX_URL = 'https://sandbox.simplify.com/v1/api';
/**
* @var string OAUTH_BASE_URL URL for the oauth endpoint
*/
const OAUTH_BASE_URL = 'https://www.simplify.com/commerce/oauth';
}

View File

@@ -0,0 +1,151 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/*
* Copyright (c) 2013 - 2015 MasterCard International Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* Neither the name of the MasterCard International Incorporated nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
class Simplify_Coupon extends Simplify_Object {
/**
* Creates an Simplify_Coupon object
* @param array $hash a map of parameters; valid keys are:<dl style="padding-left:10px;">
* <dt><tt>amountOff</tt></dt> <dd>Amount off of the price of the product in the smallest units of the currency of the merchant. While this field is optional, you must provide either amountOff or percentOff for a coupon. Example: 100 = $1.00USD [min value: 1] </dd>
* <dt><tt>couponCode</tt></dt> <dd>Code that identifies the coupon to be used. [min length: 2] <strong>required </strong></dd>
* <dt><tt>description</tt></dt> <dd>A brief section that describes the coupon. </dd>
* <dt><tt>durationInMonths</tt></dt> <dd>DEPRECATED - Duration in months that the coupon will be applied after it has first been selected. [min value: 1, max value: 9999] </dd>
* <dt><tt>endDate</tt></dt> <dd>Last date of the coupon in UTC millis that the coupon can be applied to a subscription. This ends at 23:59:59 of the merchant timezone. </dd>
* <dt><tt>maxRedemptions</tt></dt> <dd>Maximum number of redemptions allowed for the coupon. A redemption is defined as when the coupon is applied to the subscription for the first time. [min value: 1] </dd>
* <dt><tt>numTimesApplied</tt></dt> <dd>The number of times a coupon will be applied on a customer's subscription. [min value: 1, max value: 9999] </dd>
* <dt><tt>percentOff</tt></dt> <dd>Percentage off of the price of the product. While this field is optional, you must provide either amountOff or percentOff for a coupon. The percent off is a whole number. [min value: 1, max value: 100] </dd>
* <dt><tt>startDate</tt></dt> <dd>First date of the coupon in UTC millis that the coupon can be applied to a subscription. This starts at midnight of the merchant timezone. <strong>required </strong></dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.<i/>
* @return Coupon a Coupon object.
*/
static public function createCoupon($hash, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$instance = new Simplify_Coupon();
$instance->setAll($hash);
$object = Simplify_PaymentsApi::createObject($instance, $authentication);
return $object;
}
/**
* Deletes an Simplify_Coupon object.
*
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
*
* @return true
*/
public function deleteCoupon($authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 1);
$obj = Simplify_PaymentsApi::deleteObject($this, $authentication);
$this->properties = null;
return true;
}
/**
* Retrieve Simplify_Coupon objects.
* @param array criteria a map of parameters; valid keys are:<dl style="padding-left:10px;">
* <dt><tt>filter</tt></dt> <dd>Filters to apply to the list. </dd>
* <dt><tt>max</tt></dt> <dd>Allows up to a max of 50 list items to return. [min value: 0, max value: 50, default: 20] </dd>
* <dt><tt>offset</tt></dt> <dd>Used in paging of the list. This is the start offset of the page. [min value: 0, default: 0] </dd>
* <dt><tt>sorting</tt></dt> <dd>Allows for ascending or descending sorting of the list. The value maps properties to the sort direction (either <tt>asc</tt> for ascending or <tt>desc</tt> for descending). Sortable properties are: <tt> dateCreated</tt><tt> maxRedemptions</tt><tt> timesRedeemed</tt><tt> id</tt><tt> startDate</tt><tt> endDate</tt><tt> percentOff</tt><tt> couponCode</tt><tt> durationInMonths</tt><tt> numTimesApplied</tt><tt> amountOff</tt>.</dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return ResourceList a ResourceList object that holds the list of Coupon objects and the total
* number of Coupon objects available for the given criteria.
* @see ResourceList
*/
static public function listCoupon($criteria = null, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_Coupon();
$list = Simplify_PaymentsApi::listObject($val, $criteria, $authentication);
return $list;
}
/**
* Retrieve a Simplify_Coupon object from the API
*
* @param string id the id of the Coupon object to retrieve
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return Coupon a Coupon object
*/
static public function findCoupon($id, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_Coupon();
$val->id = $id;
$obj = Simplify_PaymentsApi::findObject($val, $authentication);
return $obj;
}
/**
* Updates an Simplify_Coupon object.
*
* The properties that can be updated:
* <dl style="padding-left:10px;">
* <dt><tt>endDate</tt></dt> <dd>The ending date in UTC millis for the coupon. This must be after the starting date of the coupon. </dd>
* <dt><tt>maxRedemptions</tt></dt> <dd>Maximum number of redemptions allowed for the coupon. A redemption is defined as when the coupon is applied to the subscription for the first time. [min value: 1] </dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return Coupon a Coupon object.
*/
public function updateCoupon($authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 1);
$object = Simplify_PaymentsApi::updateObject($this, $authentication);
return $object;
}
/**
* @ignore
*/
public function getClazz() {
return "Coupon";
}
}

View File

@@ -0,0 +1,184 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/*
* Copyright (c) 2013 - 2015 MasterCard International Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* Neither the name of the MasterCard International Incorporated nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
class Simplify_Customer extends Simplify_Object {
/**
* Creates an Simplify_Customer object
* @param array $hash a map of parameters; valid keys are:<dl style="padding-left:10px;">
* <dt><tt>card.addressCity</tt></dt> <dd>City of the cardholder. <strong>required </strong></dd>
* <dt><tt>card.addressCountry</tt></dt> <dd>Country code (ISO-3166-1-alpha-2 code) of residence of the cardholder. <strong>required </strong></dd>
* <dt><tt>card.addressLine1</tt></dt> <dd>Address of the cardholder <strong>required </strong></dd>
* <dt><tt>card.addressLine2</tt></dt> <dd>Address of the cardholder if needed. <strong>required </strong></dd>
* <dt><tt>card.addressState</tt></dt> <dd>State of residence of the cardholder. For the US, this is a 2-digit USPS code. <strong>required </strong></dd>
* <dt><tt>card.addressZip</tt></dt> <dd>Postal code of the cardholder. The postal code size is between 5 and 9 in length and only contain numbers or letters. <strong>required </strong></dd>
* <dt><tt>card.cvc</tt></dt> <dd>CVC security code of the card. This is the code on the back of the card. Example: 123 <strong>required </strong></dd>
* <dt><tt>card.expMonth</tt></dt> <dd>Expiration month of the card. Format is MM. Example: January = 01 <strong>required </strong></dd>
* <dt><tt>card.expYear</tt></dt> <dd>Expiration year of the card. Format is YY. Example: 2013 = 13 <strong>required </strong></dd>
* <dt><tt>card.id</tt></dt> <dd>ID of card. Unused during customer create. </dd>
* <dt><tt>card.name</tt></dt> <dd>Name as appears on the card. <strong>required </strong></dd>
* <dt><tt>card.number</tt></dt> <dd>Card number as it appears on the card. [max length: 19, min length: 13] </dd>
* <dt><tt>email</tt></dt> <dd>Email address of the customer <strong>required </strong></dd>
* <dt><tt>name</tt></dt> <dd>Customer name [min length: 2] <strong>required </strong></dd>
* <dt><tt>reference</tt></dt> <dd>Reference field for external applications use. </dd>
* <dt><tt>subscriptions.amount</tt></dt> <dd>Amount of payment in the smallest unit of your currency. Example: 100 = $1.00USD </dd>
* <dt><tt>subscriptions.billingCycle</tt></dt> <dd>How the plan is billed to the customer. Values must be AUTO (indefinitely until the customer cancels) or FIXED (a fixed number of billing cycles). [default: AUTO] </dd>
* <dt><tt>subscriptions.billingCycleLimit</tt></dt> <dd>The number of fixed billing cycles for a plan. Only used if the billingCycle parameter is set to FIXED. Example: 4 </dd>
* <dt><tt>subscriptions.coupon</tt></dt> <dd>Coupon associated with the subscription for the customer. </dd>
* <dt><tt>subscriptions.currency</tt></dt> <dd>Currency code (ISO-4217). Must match the currency associated with your account. [default: USD] </dd>
* <dt><tt>subscriptions.customer</tt></dt> <dd>The customer ID to create the subscription for. Do not supply this when creating a customer. </dd>
* <dt><tt>subscriptions.frequency</tt></dt> <dd>Frequency of payment for the plan. Used in conjunction with frequencyPeriod. Valid values are "DAILY", "WEEKLY", "MONTHLY" and "YEARLY". </dd>
* <dt><tt>subscriptions.frequencyPeriod</tt></dt> <dd>Period of frequency of payment for the plan. Example: if the frequency is weekly, and periodFrequency is 2, then the subscription is billed bi-weekly. </dd>
* <dt><tt>subscriptions.name</tt></dt> <dd>Name describing subscription </dd>
* <dt><tt>subscriptions.plan</tt></dt> <dd>The plan ID that the subscription should be created from. </dd>
* <dt><tt>subscriptions.quantity</tt></dt> <dd>Quantity of the plan for the subscription. [min value: 1] </dd>
* <dt><tt>subscriptions.renewalReminderLeadDays</tt></dt> <dd>If set, how many days before the next billing cycle that a renewal reminder is sent to the customer. If null, then no emails are sent. Minimum value is 7 if set. </dd>
* <dt><tt>token</tt></dt> <dd>If specified, card associated with card token will be used </dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.<i/>
* @return Customer a Customer object.
*/
static public function createCustomer($hash, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$instance = new Simplify_Customer();
$instance->setAll($hash);
$object = Simplify_PaymentsApi::createObject($instance, $authentication);
return $object;
}
/**
* Deletes an Simplify_Customer object.
*
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
*
* @return true
*/
public function deleteCustomer($authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 1);
$obj = Simplify_PaymentsApi::deleteObject($this, $authentication);
$this->properties = null;
return true;
}
/**
* Retrieve Simplify_Customer objects.
* @param array criteria a map of parameters; valid keys are:<dl style="padding-left:10px;">
* <dt><tt>filter</tt></dt> <dd>Filters to apply to the list. </dd>
* <dt><tt>max</tt></dt> <dd>Allows up to a max of 50 list items to return. [min value: 0, max value: 50, default: 20] </dd>
* <dt><tt>offset</tt></dt> <dd>Used in paging of the list. This is the start offset of the page. [min value: 0, default: 0] </dd>
* <dt><tt>sorting</tt></dt> <dd>Allows for ascending or descending sorting of the list. The value maps properties to the sort direction (either <tt>asc</tt> for ascending or <tt>desc</tt> for descending). Sortable properties are: <tt> dateCreated</tt><tt> id</tt><tt> name</tt><tt> email</tt><tt> reference</tt>.</dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return ResourceList a ResourceList object that holds the list of Customer objects and the total
* number of Customer objects available for the given criteria.
* @see ResourceList
*/
static public function listCustomer($criteria = null, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_Customer();
$list = Simplify_PaymentsApi::listObject($val, $criteria, $authentication);
return $list;
}
/**
* Retrieve a Simplify_Customer object from the API
*
* @param string id the id of the Customer object to retrieve
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return Customer a Customer object
*/
static public function findCustomer($id, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_Customer();
$val->id = $id;
$obj = Simplify_PaymentsApi::findObject($val, $authentication);
return $obj;
}
/**
* Updates an Simplify_Customer object.
*
* The properties that can be updated:
* <dl style="padding-left:10px;">
* <dt><tt>card.addressCity</tt></dt> <dd>City of the cardholder. <strong>required </strong></dd>
* <dt><tt>card.addressCountry</tt></dt> <dd>Country code (ISO-3166-1-alpha-2 code) of residence of the cardholder. <strong>required </strong></dd>
* <dt><tt>card.addressLine1</tt></dt> <dd>Address of the cardholder. <strong>required </strong></dd>
* <dt><tt>card.addressLine2</tt></dt> <dd>Address of the cardholder if needed. <strong>required </strong></dd>
* <dt><tt>card.addressState</tt></dt> <dd>State of residence of the cardholder. For the US, this is a 2-digit USPS code. <strong>required </strong></dd>
* <dt><tt>card.addressZip</tt></dt> <dd>Postal code of the cardholder. The postal code size is between 5 and 9 in length and only contain numbers or letters. <strong>required </strong></dd>
* <dt><tt>card.cvc</tt></dt> <dd>CVC security code of the card. This is the code on the back of the card. Example: 123 <strong>required </strong></dd>
* <dt><tt>card.expMonth</tt></dt> <dd>Expiration month of the card. Format is MM. Example: January = 01 <strong>required </strong></dd>
* <dt><tt>card.expYear</tt></dt> <dd>Expiration year of the card. Format is YY. Example: 2013 = 13 <strong>required </strong></dd>
* <dt><tt>card.id</tt></dt> <dd>ID of card. If present, card details for the customer will not be updated. If not present, the customer will be updated with the supplied card details. </dd>
* <dt><tt>card.name</tt></dt> <dd>Name as appears on the card. <strong>required </strong></dd>
* <dt><tt>card.number</tt></dt> <dd>Card number as it appears on the card. [max length: 19, min length: 13] </dd>
* <dt><tt>email</tt></dt> <dd>Email address of the customer <strong>required </strong></dd>
* <dt><tt>name</tt></dt> <dd>Customer name [min length: 2] <strong>required </strong></dd>
* <dt><tt>reference</tt></dt> <dd>Reference field for external applications use. </dd>
* <dt><tt>token</tt></dt> <dd>If specified, card associated with card token will be added to the customer </dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return Customer a Customer object.
*/
public function updateCustomer($authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 1);
$object = Simplify_PaymentsApi::updateObject($this, $authentication);
return $object;
}
/**
* @ignore
*/
public function getClazz() {
return "Customer";
}
}

View File

@@ -0,0 +1,86 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/*
* Copyright (c) 2013 - 2015 MasterCard International Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* Neither the name of the MasterCard International Incorporated nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
class Simplify_Deposit extends Simplify_Object {
/**
* Retrieve Simplify_Deposit objects.
* @param array criteria a map of parameters; valid keys are:<dl style="padding-left:10px;">
* <dt><tt>filter</tt></dt> <dd>Filters to apply to the list. </dd>
* <dt><tt>max</tt></dt> <dd>Allows up to a max of 50 list items to return. [min value: 0, max value: 50, default: 20] </dd>
* <dt><tt>offset</tt></dt> <dd>Used in paging of the list. This is the start offset of the page. [min value: 0, default: 0] </dd>
* <dt><tt>sorting</tt></dt> <dd>Allows for ascending or descending sorting of the list. The value maps properties to the sort direction (either <tt>asc</tt> for ascending or <tt>desc</tt> for descending). Sortable properties are: <tt> amount</tt><tt> dateCreated</tt><tt> depositDate</tt>.</dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return ResourceList a ResourceList object that holds the list of Deposit objects and the total
* number of Deposit objects available for the given criteria.
* @see ResourceList
*/
static public function listDeposit($criteria = null, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_Deposit();
$list = Simplify_PaymentsApi::listObject($val, $criteria, $authentication);
return $list;
}
/**
* Retrieve a Simplify_Deposit object from the API
*
* @param string id the id of the Deposit object to retrieve
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return Deposit a Deposit object
*/
static public function findDeposit($id, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_Deposit();
$val->id = $id;
$obj = Simplify_PaymentsApi::findObject($val, $authentication);
return $obj;
}
/**
* @ignore
*/
public function getClazz() {
return "Deposit";
}
}

View File

@@ -0,0 +1,68 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/*
* Copyright (c) 2013 - 2015 MasterCard International Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* Neither the name of the MasterCard International Incorporated nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
class Simplify_Event extends Simplify_Object {
/**
* Creates an Event object
* @param array $hash A map of parameters; valid keys are:
* <dt><code>payload</code></dt> <dd>The raw JWS payload. </dd> <strong>required</strong>
* <dt><code>url</code></dt> <dd>The URL for the webhook. If present it must match the URL registered for the webhook.</dd>
* @param $authentication Object that contains the API public and private keys. If null the values of the static
* Simplify::$publicKey and Simplify::$privateKey will be used.
* @return Payments_Event an Event object.
* @throws InvalidArgumentException
*/
static public function createEvent($hash, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$paymentsApi = new Simplify_PaymentsApi();
$jsonObject = $paymentsApi->jwsDecode($hash, $authentication);
if ($jsonObject['event'] == null) {
throw new InvalidArgumentException("Incorrect data in webhook event");
}
return $paymentsApi->convertFromHashToObject($jsonObject['event'], self::getClazz());
}
/**
* @ignore
*/
static public function getClazz() {
return "Event";
}
}

View File

@@ -0,0 +1,294 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/*
* Copyright (c) 2013 - 2015 MasterCard International Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* Neither the name of the MasterCard International Incorporated nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
*
* Base class for all API exceptions.
*
*/
class Simplify_ApiException extends Exception
{
protected $errorData;
protected $status;
protected $errorCode;
protected $reference;
/**
* @ignore
*/
function __construct($message, $status = null, $errorData = null) {
parent::__construct($message);
$this->status = $status;
$this->errorCode = null;
$this->reference = null;
if ($errorData != null) {
$this->reference = $errorData['reference'];
$this->errorData = $errorData;
$error = $errorData['error'];
if ($error != null) {
$m = $error['message'];
if ($m != null) {
$this->message = $m;
}
$this->errorCode = $error['code'];
}
}
}
/**
* Returns a map of all error data returned by the API.
* @return array a map containing API error data.
*/
function getErrorData() {
return $this->errorData;
}
/**
* Returns the HTTP status for the request.
* @return string HTTP status code (or null if there is no status).
*/
function getStatus() {
return $this->status;
}
/**
* Returns unique reference for the API error.
* @return string a reference (or null if there is no reference).
*/
function getReference() {
return $this->reference;
}
/**
* Returns an code for the API error.
* @return string the error code.
*/
function getErrorCode() {
return $this->errorCode;
}
/**
* Returns a description of the error.
* @return string Description of the error.
*/
function describe() {
return get_class($this) . ": \""
. $this->getMessage() . "\" (status: "
. $this->getStatus() . ", error code: "
. $this->getErrorCode() . ", reference: "
. $this->getReference() . ")";
}
}
/**
* Exception raised when there are communication problems contacting the API.
*/
class Simplify_ApiConnectionException extends Simplify_ApiException {
/**
* @ignore
*/
function __construct($message, $status = null, $errorData = null) {
parent::__construct($message, $status, $errorData);
}
}
/**
* Exception raised where there are problems authenticating a request.
*/
class Simplify_AuthenticationException extends Simplify_ApiException {
/**
* @ignore
*/
function __construct($message, $status = null, $errorData = null) {
parent::__construct($message, $status, $errorData);
}
}
/**
* Exception raised when the API request contains errors.
*/
class Simplify_BadRequestException extends Simplify_ApiException {
protected $fieldErrors;
/**
* @ignore
*/
function __construct($message, $status = null, $errorData = null) {
parent::__construct($message, $status, $errorData);
$fieldErrors = array();
if ($errorData != null) {
$error = $errorData['error'];
if ($error != null) {
$fieldErrors = $error['fieldErrors'];
if ($fieldErrors != null) {
$this->fieldErrors = array();
foreach ($fieldErrors as $fieldError) {
array_push($this->fieldErrors, new Simplify_FieldError($fieldError));
}
}
}
}
}
/**
* Returns a boolean indicating whether there are any field errors.
* @return boolean true if there are field errors; false otherwise.
*/
function hasFieldErrors() {
return count($this->fieldErrors) > 0;
}
/**
* Returns a list containing all field errors.
* @return array list of field errors.
*/
function getFieldErrors() {
return $this->fieldErrors;
}
/**
* Returns a description of the error.
* @return string description of the error.
*/
function describe() {
$s = parent::describe();
foreach ($this->getFieldErrors() as $fieldError) {
$s = $s . "\n" . (string) $fieldError;
}
return $s . "\n";
}
}
/**
* Represents a single error in a field of a request sent to the API.
*/
class Simplify_FieldError {
protected $field;
protected $code;
protected $message;
/**
* @ignore
*/
function __construct($errorData) {
$this->field = $errorData['field'];
$this->code = $errorData['code'];
$this->message = $errorData['message'];
}
/**
* Returns the name of the field with the error.
* @return string the field name.
*/
function getFieldName() {
return $this->field;
}
/**
* Returns the code for the error.
* @return string the error code.
*/
function getErrorCode() {
return $this->code;
}
/**
* Returns a description of the error.
* @return string description of the error.
*/
function getMessage() {
return $this->message;
}
function __toString() {
return "Field error: " . $this->getFieldName() . "\"" . $this->getMessage() . "\" (" . $this->getErrorCode() . ")";
}
}
/**
* Exception when a requested object cannot be found.
*/
class Simplify_ObjectNotFoundException extends Simplify_ApiException {
/**
* @ignore
*/
function __construct($message, $status = null, $errorData = null) {
parent::__construct($message, $status, $errorData);
}
}
/**
* Exception when a request was not allowed.
*/
class Simplify_NotAllowedException extends Simplify_ApiException {
/**
* @ignore
*/
function __construct($message, $status = null, $errorData = null) {
parent::__construct($message, $status, $errorData);
}
}
/**
* Exception when there was a system error processing a request.
*/
class Simplify_SystemException extends Simplify_ApiException {
/**
* @ignore
*/
function __construct($message, $status = null, $errorData = null) {
parent::__construct($message, $status, $errorData);
}
}

View File

@@ -0,0 +1,122 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/*
* Copyright (c) 2013 - 2015 MasterCard International Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* Neither the name of the MasterCard International Incorporated nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
class Simplify_FraudCheck extends Simplify_Object {
/**
* Creates an Simplify_FraudCheck object
* @param array $hash a map of parameters; valid keys are:<dl style="padding-left:10px;">
* <dt><tt>amount</tt></dt> <dd>Amount of the transaction to be checked for fraud (in the smallest unit of your currency). Example: 100 = $1.00USD </dd>
* <dt><tt>card.addressCity</tt></dt> <dd>City of the cardholder. [max length: 50, min length: 2] </dd>
* <dt><tt>card.addressCountry</tt></dt> <dd>Country code (ISO-3166-1-alpha-2 code) of residence of the cardholder. [max length: 2, min length: 2] </dd>
* <dt><tt>card.addressLine1</tt></dt> <dd>Address of the cardholder. [max length: 255] </dd>
* <dt><tt>card.addressLine2</tt></dt> <dd>Address of the cardholder if needed. [max length: 255] </dd>
* <dt><tt>card.addressState</tt></dt> <dd>State of residence of the cardholder. For the US, this is a 2-digit USPS code. [max length: 255, min length: 2] </dd>
* <dt><tt>card.addressZip</tt></dt> <dd>Postal code of the cardholder. The postal code size is between 5 and 9 characters in length and only contains numbers or letters. [max length: 9, min length: 3] </dd>
* <dt><tt>card.cvc</tt></dt> <dd>CVC security code of the card. This is the code on the back of the card. Example: 123 </dd>
* <dt><tt>card.expMonth</tt></dt> <dd>Expiration month of the card. Format is MM. Example: January = 01 [min value: 1, max value: 12] <strong>required </strong></dd>
* <dt><tt>card.expYear</tt></dt> <dd>Expiration year of the card. Format is YY. Example: 2013 = 13 [min value: 0, max value: 99] <strong>required </strong></dd>
* <dt><tt>card.name</tt></dt> <dd>Name as it appears on the card. [max length: 50, min length: 2] </dd>
* <dt><tt>card.number</tt></dt> <dd>Card number as it appears on the card. [max length: 19, min length: 13] <strong>required </strong></dd>
* <dt><tt>currency</tt></dt> <dd>Currency code (ISO-4217) for the transaction to be checked for fraud. </dd>
* <dt><tt>description</tt></dt> <dd>- Description of the fraud check. </dd>
* <dt><tt>mode</tt></dt> <dd>Fraud check mode. “simple” only does an AVS and CVC check; “advanced” does a complete fraud check, running the input against the set up rules. [valid values: simple, advanced, full] <strong>required </strong></dd>
* <dt><tt>sessionId</tt></dt> <dd>Session ID usd during data collection. [max length: 255] </dd>
* <dt><tt>token</tt></dt> <dd>Description </dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.<i/>
* @return FraudCheck a FraudCheck object.
*/
static public function createFraudCheck($hash, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$instance = new Simplify_FraudCheck();
$instance->setAll($hash);
$object = Simplify_PaymentsApi::createObject($instance, $authentication);
return $object;
}
/**
* Retrieve Simplify_FraudCheck objects.
* @param array criteria a map of parameters; valid keys are:<dl style="padding-left:10px;">
* <dt><tt>filter</tt></dt> <dd>Allows for ascending or descending sorting of the list. </dd>
* <dt><tt>max</tt></dt> <dd>Allows up to a max of 50 list items to return. [min value: 0, max value: 50, default: 20] </dd>
* <dt><tt>offset</tt></dt> <dd>Used in paging of the list. This is the start offset of the page. [min value: 0, default: 0] </dd>
* <dt><tt>sorting</tt></dt> <dd>Used in paging of the list. This is the start offset of the page. The value maps properties to the sort direction (either <tt>asc</tt> for ascending or <tt>desc</tt> for descending). Sortable properties are: .</dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return ResourceList a ResourceList object that holds the list of FraudCheck objects and the total
* number of FraudCheck objects available for the given criteria.
* @see ResourceList
*/
static public function listFraudCheck($criteria = null, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_FraudCheck();
$list = Simplify_PaymentsApi::listObject($val, $criteria, $authentication);
return $list;
}
/**
* Retrieve a Simplify_FraudCheck object from the API
*
* @param string id the id of the FraudCheck object to retrieve
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return FraudCheck a FraudCheck object
*/
static public function findFraudCheck($id, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_FraudCheck();
$val->id = $id;
$obj = Simplify_PaymentsApi::findObject($val, $authentication);
return $obj;
}
/**
* @ignore
*/
public function getClazz() {
return "FraudCheck";
}
}

View File

@@ -0,0 +1,411 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/*
* Copyright (c) 2013 - 2015 MasterCard International Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* Neither the name of the MasterCard International Incorporated nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
class Simplify_HTTP
{
const DELETE = "DELETE";
const GET = "GET";
const POST = "POST";
const PUT = "PUT";
const HTTP_SUCCESS = 200;
const HTTP_REDIRECTED = 302;
const HTTP_UNAUTHORIZED = 401;
const HTTP_NOT_FOUND = 404;
const HTTP_NOT_ALLOWED = 405;
const HTTP_BAD_REQUEST = 400;
const JWS_NUM_HEADERS = 7;
const JWS_ALGORITHM = 'HS256';
const JWS_TYPE = 'JWS';
const JWS_HDR_UNAME = 'uname';
const JWS_HDR_URI = 'api.simplifycommerce.com/uri';
const JWS_HDR_TIMESTAMP = 'api.simplifycommerce.com/timestamp';
const JWS_HDR_NONCE = 'api.simplifycommerce.com/nonce';
const JWS_HDR_TOKEN = 'api.simplifycommerce.com/token';
const JWS_MAX_TIMESTAMP_DIFF = 300; // 5 minutes in seconds
static private $_validMethods = array(
"post" => self::POST,
"put" => self::PUT,
"get" => self::GET,
"delete" => self::DELETE);
private function request($url, $method, $authentication, $payload = '')
{
if ($authentication->publicKey == null) {
throw new InvalidArgumentException('Must have a valid public key to connect to the API');
}
if ($authentication->privateKey == null) {
throw new InvalidArgumentException('Must have a valid API key to connect to the API');
}
if (!array_key_exists(strtolower($method), self::$_validMethods)) {
throw new InvalidArgumentException('Invalid method: '.strtolower($method));
}
$method = self::$_validMethods[strtolower($method)];
$curl = curl_init();
$options = array();
$options[CURLOPT_URL] = $url;
$options[CURLOPT_CUSTOMREQUEST] = $method;
$options[CURLOPT_RETURNTRANSFER] = true;
$options[CURLOPT_FAILONERROR] = false;
$signature = $this->jwsEncode($authentication, $url, $payload, $method == self::POST || $method == self::PUT);
if ($method == self::POST || $method == self::PUT) {
$headers = array(
'Content-type: application/json'
);
$options[CURLOPT_POSTFIELDS] = $signature;
} else {
$headers = array(
'Authorization: JWS ' . $signature
);
}
array_push($headers, 'Accept: application/json');
$user_agent = 'PHP-SDK/' . Simplify_Constants::VERSION;
if (Simplify::$userAgent != null) {
$user_agent = $user_agent . ' ' . Simplify::$userAgent;
}
array_push($headers, 'User-Agent: ' . $user_agent);
$options[CURLOPT_HTTPHEADER] = $headers;
curl_setopt_array($curl, $options);
$data = curl_exec($curl);
$errno = curl_errno($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($data == false || $errno != CURLE_OK) {
throw new Simplify_ApiConnectionException(curl_error($curl));
}
$object = json_decode($data, true);
//'typ' => self::JWS_TYPE,
$response = array('status' => $status, 'object' => $object);
return $response;
curl_close($curl);
}
/**
* Handles Simplify API requests
*
* @param $url
* @param $method
* @param $authentication
* @param string $payload
* @return mixed
* @throws Simplify_AuthenticationException
* @throws Simplify_ObjectNotFoundException
* @throws Simplify_BadRequestException
* @throws Simplify_NotAllowedException
* @throws Simplify_SystemException
*/
public function apiRequest($url, $method, $authentication, $payload = ''){
$response = $this->request($url, $method, $authentication, $payload);
$status = $response['status'];
$object = $response['object'];
if ($status == self::HTTP_SUCCESS) {
return $object;
}
if ($status == self::HTTP_REDIRECTED) {
throw new Simplify_BadRequestException("Unexpected response code returned from the API, have you got the correct URL?", $status, $object);
} else if ($status == self::HTTP_BAD_REQUEST) {
throw new Simplify_BadRequestException("Bad request", $status, $object);
} else if ($status == self::HTTP_UNAUTHORIZED) {
throw new Simplify_AuthenticationException("You are not authorized to make this request. Are you using the correct API keys?", $status, $object);
} else if ($status == self::HTTP_NOT_FOUND) {
throw new Simplify_ObjectNotFoundException("Object not found", $status, $object);
} else if ($status == self::HTTP_NOT_ALLOWED) {
throw new Simplify_NotAllowedException("Operation not allowed", $status, $object);
} else if ($status < 500) {
throw new Simplify_BadRequestException("Bad request", $status, $object);
}
throw new Simplify_SystemException("An unexpected error has been raised. Looks like there's something wrong at our end." , $status, $object);
}
/**
* Handles Simplify OAuth requests
*
* @param $url
* @param $payload
* @param $authentication
* @return mixed
* @throws Simplify_AuthenticationException
* @throws Simplify_ObjectNotFoundException
* @throws Simplify_BadRequestException
* @throws Simplify_NotAllowedException
* @throws Simplify_SystemException
*/
public function oauthRequest($url, $payload, $authentication){
$response = $this->request($url, Simplify_HTTP::POST, $authentication, $payload);
$status = $response['status'];
$object = $response['object'];
if ($status == self::HTTP_SUCCESS) {
return $object;
}
$error = $object['error'];
$error_description = $object['error_description'];
if ($status == self::HTTP_REDIRECTED) {
throw new Simplify_BadRequestException("Unexpected response code returned from the API, have you got the correct URL?", $status, $object);
} else if ($status == self::HTTP_BAD_REQUEST) {
if ( $error == 'invalid_request'){
throw new Simplify_BadRequestException("", $status, $this->buildOauthError('Error during OAuth request', $error, $error_description));
}else if ($error == 'unsupported_grant_type'){
throw new Simplify_BadRequestException("", $status, $this->buildOauthError('Unsupported grant type in OAuth request', $error, $error_description));
}else if ($error == 'invalid_scope'){
throw new Simplify_BadRequestException("", $status, $this->buildOauthError('Invalid scope in OAuth request', $error, $error_description));
}else{
throw new Simplify_BadRequestException("", $status, $this->buildOauthError('Unknown OAuth error', $error, $error_description));
}
//TODO: build BadRequestException error JSON
} else if ($status == self::HTTP_UNAUTHORIZED){
if ($error == 'access_denied'){
throw new Simplify_AuthenticationException("", $status, $this->buildOauthError('Access denied for OAuth request', $error, $error_description));
}else if ($error == 'invalid_client'){
throw new Simplify_AuthenticationException("", $status, $this->buildOauthError('Invalid client ID in OAuth request', $error, $error_description));
}else if ($error == 'unauthorized_client'){
throw new Simplify_AuthenticationException("", $status, $this->buildOauthError('Unauthorized client in OAuth request', $error, $error_description));
}else{
throw new Simplify_AuthenticationException("", $status, $this->buildOauthError('Unknown authentication error', $error, $error_description));
}
} else if ($status < 500) {
throw new Simplify_BadRequestException("Bad request", $status, $object);
}
throw new Simplify_SystemException("An unexpected error has been raised. Looks like there's something wrong at our end." , $status, $object);
}
public function jwsDecode($authentication, $hash)
{
if ($authentication->publicKey == null) {
throw new InvalidArgumentException('Must have a valid public key to connect to the API');
}
if ($authentication->privateKey == null) {
throw new InvalidArgumentException('Must have a valid API key to connect to the API');
}
if (!isset($hash['payload'])) {
throw new InvalidArgumentException('Event data is Missing payload');
}
$payload = trim($hash['payload']);
try {
$parts = explode('.', $payload);
if (count($parts) != 3) {
$this->jwsAuthError("Incorrectly formatted JWS message");
}
$headerStr = $this->jwsUrlSafeDecode64($parts[0]);
$bodyStr = $this->jwsUrlSafeDecode64($parts[1]);
$sigStr = $parts[2];
$url = null;
if (isset($hash['url'])) {
$url = $hash['url'];
}
$this->jwsVerifyHeader($headerStr, $url, $authentication->publicKey);
$msg = $parts[0] . "." . $parts[1];
if (!$this->jwsVerifySignature($authentication->privateKey, $msg, $sigStr)) {
$this->jwsAuthError("JWS signature does not match");
}
return $bodyStr;
} catch (ApiException $e) {
throw $e;
} catch (Exception $e) {
$this->jwsAuthError("Exception during JWS decoding: " . $e);
}
}
private function jwsEncode($authentication, $url, $payload, $hasPayload)
{
// TODO - better seeding of RNG
$jws_hdr = array('typ' => self::JWS_TYPE,
'alg' => self::JWS_ALGORITHM,
'kid' => $authentication->publicKey,
self::JWS_HDR_URI => $url,
self::JWS_HDR_TIMESTAMP => sprintf("%u000", round(microtime(true))),
self::JWS_HDR_NONCE => sprintf("%u", mt_rand()),
);
// add oauth token if provided
if ( !empty($authentication->accessToken) ){
$jws_hdr[self::JWS_HDR_TOKEN] = $authentication->accessToken;
}
$header = $this->jwsUrlSafeEncode64(json_encode($jws_hdr));
if ($hasPayload) {
$payload = $this->jwsUrlSafeEncode64($payload);
} else {
$payload = '';
}
$msg = $header . "." . $payload;
return $msg . "." . $this->jwsSign($authentication->privateKey, $msg);
}
private function jwsSign($privateKey, $msg) {
$decodedPrivateKey = $this->jwsUrlSafeDecode64($privateKey);
$sig = hash_hmac('sha256', $msg, $decodedPrivateKey, true);
return $this->jwsUrlSafeEncode64($sig);
}
private function jwsVerifyHeader($header, $url, $publicKey) {
$hdr = json_decode($header, true);
if (count($hdr) != self::JWS_NUM_HEADERS) {
$this->jwsAuthError("Incorrect number of JWS header parameters - found " . count($hdr) . " required " . self::JWS_NUM_HEADERS);
}
if ($hdr['alg'] != self::JWS_ALGORITHM) {
$this->jwsAuthError("Incorrect algorithm - found " . $hdr['alg'] . " required " . self::WS_ALGORITHM);
}
if ($hdr['typ'] != self::JWS_TYPE) {
$this->jwsAuthError("Incorrect type - found " . $hdr['typ'] . " required " . self::JWS_TYPE);
}
if ($hdr['kid'] == null) {
$this->jwsAuthError("Missing Key ID");
}
if ($hdr['kid'] != $publicKey) {
if ($this->isLiveKey($publicKey)) {
$this->jwsAuthError("Invalid Key ID");
}
}
if ($hdr[self::JWS_HDR_URI] == null) {
$this->jwsAuthError("Missing URI");
}
if ($url != null && $hdr[self::JWS_HDR_URI] != $url) {
$this->jwsAuthError("Incorrect URL - found " . $hdr[self::JWS_HDR_URI] . " required " . $url);
}
if ($hdr[self::JWS_HDR_TIMESTAMP] == null) {
$this->jwsAuthError("Missing timestamp");
}
if (!$this->jwsVerifyTimestamp($hdr[self::JWS_HDR_TIMESTAMP])) {
$this->jwsAuthError("Invalid timestamp");
}
if ($hdr[self::JWS_HDR_NONCE] == null) {
$this->jwsAuthError("Missing nonce");
}
if ($hdr[self::JWS_HDR_UNAME] == null) {
$this->jwsAuthError("Missing username");
}
}
private function jwsVerifySignature($privateKey, $msg, $expectedSig) {
return $this->jwsSign($privateKey, $msg) == $expectedSig;
}
private function jwsAuthError($reason) {
throw new Simplify_AuthenticationException("JWS authentication failure: " . $reason);
}
private function jwsVerifyTimestamp($ts) {
$now = round(microtime(true)); // Seconds
return abs($now - $ts / 1000) < self::JWS_MAX_TIMESTAMP_DIFF;
}
private function isLiveKey($k) {
return strpos($k, "lvpb") === 0;
}
private function jwsUrlSafeEncode64($s) {
return str_replace(array('+', '/', '='),
array('-', '_', ''),
base64_encode($s));
}
private function jwsUrlSafeDecode64($s) {
switch (strlen($s) % 4) {
case 0: break;
case 2: $s = $s . "==";
break;
case 3: $s = $s . "=";
break;
default: throw new InvalidArgumentException('incorrectly formatted JWS payload');
}
return base64_decode(str_replace(array('-', '_'), array('+', '/'), $s));
}
private function buildOauthError($msg, $error, $error_description){
return array(
'error' => array(
'code' => 'oauth_error',
'message' => $msg.', error code: '.$error.', description: '.$error_description.''
)
);
}
}

View File

@@ -0,0 +1,228 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/*
* Copyright (c) 2013 - 2015 MasterCard International Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* Neither the name of the MasterCard International Incorporated nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
class Simplify_Invoice extends Simplify_Object {
/**
* Creates an Simplify_Invoice object
* @param array $hash a map of parameters; valid keys are:<dl style="padding-left:10px;">
* <dt><tt>billingAddress.city</tt></dt> <dd>Billing address city of the location where the goods or services were supplied. [max length: 255, min length: 2] </dd>
* <dt><tt>billingAddress.country</tt></dt> <dd>Billing address country of the location where the goods or services were supplied. [max length: 2, min length: 2] </dd>
* <dt><tt>billingAddress.line1</tt></dt> <dd>Billing address line 1 of the location where the goods or services were supplied. [max length: 255] </dd>
* <dt><tt>billingAddress.line2</tt></dt> <dd>Billing address line 2 of the location where the goods or services were supplied. [max length: 255] </dd>
* <dt><tt>billingAddress.name</tt></dt> <dd>Billing address name of the location where the goods or services were supplied. Will use the customer name if not provided. [max length: 255] </dd>
* <dt><tt>billingAddress.state</tt></dt> <dd>Billing address state of the location where the goods or services were supplied. [max length: 255] </dd>
* <dt><tt>billingAddress.zip</tt></dt> <dd>Billing address zip of the location where the goods or services were supplied. [max length: 32] </dd>
* <dt><tt>businessAddress.city</tt></dt> <dd>Address city of the business that is sending the invoice. [max length: 255, min length: 2] </dd>
* <dt><tt>businessAddress.country</tt></dt> <dd>Address country of the business that is sending the invoice. [max length: 2, min length: 2] </dd>
* <dt><tt>businessAddress.line1</tt></dt> <dd>Address line 1 of the business that is sending the invoice. [max length: 255] </dd>
* <dt><tt>businessAddress.line2</tt></dt> <dd>Address line 2 of the business that is sending the invoice. [max length: 255] </dd>
* <dt><tt>businessAddress.name</tt></dt> <dd>The name of the business that is sending the invoice. [max length: 255] </dd>
* <dt><tt>businessAddress.state</tt></dt> <dd>Address state of the business that is sending the invoice. [max length: 255] </dd>
* <dt><tt>businessAddress.zip</tt></dt> <dd>Address zip of the business that is sending the invoice. [max length: 32] </dd>
* <dt><tt>currency</tt></dt> <dd>Currency code (ISO-4217). Must match the currency associated with your account. [max length: 3, min length: 3, default: USD] </dd>
* <dt><tt>customer</tt></dt> <dd>The customer ID of the customer we are invoicing. This is optional if invoiceToCopy or a name and email are provided </dd>
* <dt><tt>customerTaxNo</tt></dt> <dd>The tax number or VAT id of the person to whom the goods or services were supplied. [max length: 255] </dd>
* <dt><tt>discountRate</tt></dt> <dd>The discount percent as a decimal e.g. 12.5. This is used to calculate the discount amount which is subtracted from the total amount due before any tax is applied. [max length: 6] </dd>
* <dt><tt>dueDate</tt></dt> <dd>The date invoice payment is due. If a late fee is provided this will be added to the invoice total is the due date has past. </dd>
* <dt><tt>email</tt></dt> <dd>The email of the customer we are invoicing. This is optional if customer or invoiceToCopy is provided. A new customer will be created using the the name and email. </dd>
* <dt><tt>invoiceId</tt></dt> <dd>User defined invoice id. If not provided the system will generate a numeric id. [max length: 255] </dd>
* <dt><tt>invoiceToCopy</tt></dt> <dd>The id of an existing invoice to be copied. This is optional if customer or a name and email are provided </dd>
* <dt><tt>items.amount</tt></dt> <dd>Amount of the invoice item (the smallest unit of your currency). Example: 100 = $1.00USD [min value: -9999900, max value: 9999900] <strong>required </strong></dd>
* <dt><tt>items.description</tt></dt> <dd>The description of the invoice item. [max length: 1024] </dd>
* <dt><tt>items.invoice</tt></dt> <dd>The ID of the invoice this item belongs to. </dd>
* <dt><tt>items.product</tt></dt> <dd>The product this invoice item refers to. </dd>
* <dt><tt>items.quantity</tt></dt> <dd>Quantity of the item. This total amount of the invoice item is the amount * quantity. [min value: 1, max value: 999999, default: 1] </dd>
* <dt><tt>items.reference</tt></dt> <dd>User defined reference field. [max length: 255] </dd>
* <dt><tt>items.tax</tt></dt> <dd>The tax ID of the tax charge in the invoice item. </dd>
* <dt><tt>lateFee</tt></dt> <dd>The late fee amount that will be added to the invoice total is the due date is past due. Value provided must be in the smallest unit of your currency. Example: 100 = $1.00USD [max value: 9999900] </dd>
* <dt><tt>memo</tt></dt> <dd>A memo that is displayed to the customer on the invoice payment screen. [max length: 4000] </dd>
* <dt><tt>name</tt></dt> <dd>The name of the customer we are invoicing. This is optional if customer or invoiceToCopy is provided. A new customer will be created using the the name and email. [max length: 50, min length: 2] </dd>
* <dt><tt>note</tt></dt> <dd>This field can be used to store a note that is not displayed to the customer. [max length: 4000] </dd>
* <dt><tt>reference</tt></dt> <dd>User defined reference field. [max length: 255] </dd>
* <dt><tt>shippingAddress.city</tt></dt> <dd>Address city of the location where the goods or services were supplied. [max length: 255, min length: 2] </dd>
* <dt><tt>shippingAddress.country</tt></dt> <dd>Address country of the location where the goods or services were supplied. [max length: 2, min length: 2] </dd>
* <dt><tt>shippingAddress.line1</tt></dt> <dd>Address line 1 of the location where the goods or services were supplied. [max length: 255] </dd>
* <dt><tt>shippingAddress.line2</tt></dt> <dd>Address line 2 of the location where the goods or services were supplied. [max length: 255] </dd>
* <dt><tt>shippingAddress.name</tt></dt> <dd>Address name of the location where the goods or services were supplied. [max length: 255] </dd>
* <dt><tt>shippingAddress.state</tt></dt> <dd>Address state of the location where the goods or services were supplied. [max length: 255] </dd>
* <dt><tt>shippingAddress.zip</tt></dt> <dd>Address zip of the location where the goods or services were supplied. [max length: 32] </dd>
* <dt><tt>suppliedDate</tt></dt> <dd>The date on which the goods or services were supplied. </dd>
* <dt><tt>taxNo</tt></dt> <dd>The tax number or VAT id of the person who supplied the goods or services. [max length: 255] </dd>
* <dt><tt>type</tt></dt> <dd>The type of invoice. One of WEB or MOBILE. [valid values: WEB, MOBILE, default: WEB] </dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.<i/>
* @return Invoice a Invoice object.
*/
static public function createInvoice($hash, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$instance = new Simplify_Invoice();
$instance->setAll($hash);
$object = Simplify_PaymentsApi::createObject($instance, $authentication);
return $object;
}
/**
* Deletes an Simplify_Invoice object.
*
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
*
* @return true
*/
public function deleteInvoice($authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 1);
$obj = Simplify_PaymentsApi::deleteObject($this, $authentication);
$this->properties = null;
return true;
}
/**
* Retrieve Simplify_Invoice objects.
* @param array criteria a map of parameters; valid keys are:<dl style="padding-left:10px;">
* <dt><tt>filter</tt></dt> <dd>Filters to apply to the list. </dd>
* <dt><tt>max</tt></dt> <dd>Allows up to a max of 50 list items to return. [min value: 0, max value: 50, default: 20] </dd>
* <dt><tt>offset</tt></dt> <dd>Used in paging of the list. This is the start offset of the page. [min value: 0, default: 0] </dd>
* <dt><tt>sorting</tt></dt> <dd>Allows for ascending or descending sorting of the list. The value maps properties to the sort direction (either <tt>asc</tt> for ascending or <tt>desc</tt> for descending). Sortable properties are: <tt> id</tt><tt> invoiceDate</tt><tt> dueDate</tt><tt> datePaid</tt><tt> customer</tt><tt> status</tt><tt> dateCreated</tt>.</dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return ResourceList a ResourceList object that holds the list of Invoice objects and the total
* number of Invoice objects available for the given criteria.
* @see ResourceList
*/
static public function listInvoice($criteria = null, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_Invoice();
$list = Simplify_PaymentsApi::listObject($val, $criteria, $authentication);
return $list;
}
/**
* Retrieve a Simplify_Invoice object from the API
*
* @param string id the id of the Invoice object to retrieve
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return Invoice a Invoice object
*/
static public function findInvoice($id, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_Invoice();
$val->id = $id;
$obj = Simplify_PaymentsApi::findObject($val, $authentication);
return $obj;
}
/**
* Updates an Simplify_Invoice object.
*
* The properties that can be updated:
* <dl style="padding-left:10px;">
* <dt><tt>billingAddress.city</tt></dt> <dd>Billing address city of the location where the goods or services were supplied. [max length: 255, min length: 2] </dd>
* <dt><tt>billingAddress.country</tt></dt> <dd>Billing address country of the location where the goods or services were supplied. [max length: 2, min length: 2] </dd>
* <dt><tt>billingAddress.line1</tt></dt> <dd>Billing address line 1 of the location where the goods or services were supplied. [max length: 255] </dd>
* <dt><tt>billingAddress.line2</tt></dt> <dd>Billing address line 2 of the location where the goods or services were supplied. [max length: 255] </dd>
* <dt><tt>billingAddress.name</tt></dt> <dd>Billing address name of the location where the goods or services were supplied. [max length: 255] </dd>
* <dt><tt>billingAddress.state</tt></dt> <dd>Billing address state of the location where the goods or services were supplied. [max length: 255] </dd>
* <dt><tt>billingAddress.zip</tt></dt> <dd>Billing address zip of the location where the goods or services were supplied. [max length: 32] </dd>
* <dt><tt>businessAddress.city</tt></dt> <dd>Business address city of the business that is sending the invoice. [max length: 255, min length: 2] </dd>
* <dt><tt>businessAddress.country</tt></dt> <dd>Business address country of the business that is sending the invoice. [max length: 2, min length: 2] </dd>
* <dt><tt>businessAddress.line1</tt></dt> <dd>Business address line 1 of the business that is sending the invoice. [max length: 255] </dd>
* <dt><tt>businessAddress.line2</tt></dt> <dd>Business address line 2 of the business that is sending the invoice. [max length: 255] </dd>
* <dt><tt>businessAddress.name</tt></dt> <dd>Business address name of the business that is sending the invoice. [max length: 255] </dd>
* <dt><tt>businessAddress.state</tt></dt> <dd>Business address state of the business that is sending the invoice. [max length: 255] </dd>
* <dt><tt>businessAddress.zip</tt></dt> <dd>Business address zip of the business that is sending the invoice. [max length: 32] </dd>
* <dt><tt>currency</tt></dt> <dd>Currency code (ISO-4217). Must match the currency associated with your account. [max length: 3, min length: 3] </dd>
* <dt><tt>customerTaxNo</tt></dt> <dd>The tax number or VAT id of the person to whom the goods or services were supplied. [max length: 255] </dd>
* <dt><tt>datePaid</tt></dt> <dd>This is the date the invoice was PAID in UTC millis. </dd>
* <dt><tt>discountRate</tt></dt> <dd>The discount percent as a decimal e.g. 12.5. This is used to calculate the discount amount which is subtracted from the total amount due before any tax is applied. [max length: 6] </dd>
* <dt><tt>dueDate</tt></dt> <dd>The date invoice payment is due. If a late fee is provided this will be added to the invoice total is the due date has past. </dd>
* <dt><tt>email</tt></dt> <dd>The email of the customer we are invoicing. This is optional if customer or invoiceToCopy is provided. A new customer will be created using the the name and email. </dd>
* <dt><tt>invoiceId</tt></dt> <dd>User defined invoice id. If not provided the system will generate a numeric id. [max length: 255] </dd>
* <dt><tt>items.amount</tt></dt> <dd>Amount of the invoice item in the smallest unit of your currency. Example: 100 = $1.00USD [min value: -9999900, max value: 9999900] <strong>required </strong></dd>
* <dt><tt>items.description</tt></dt> <dd>The description of the invoice item. [max length: 1024] </dd>
* <dt><tt>items.invoice</tt></dt> <dd>The ID of the invoice this item belongs to. </dd>
* <dt><tt>items.product</tt></dt> <dd>The Id of the product this item refers to. </dd>
* <dt><tt>items.quantity</tt></dt> <dd>Quantity of the item. This total amount of the invoice item is the amount * quantity. [min value: 1, max value: 999999, default: 1] </dd>
* <dt><tt>items.reference</tt></dt> <dd>User defined reference field. [max length: 255] </dd>
* <dt><tt>items.tax</tt></dt> <dd>The tax ID of the tax charge in the invoice item. </dd>
* <dt><tt>lateFee</tt></dt> <dd>The late fee amount that will be added to the invoice total is the due date is past due. Value provided must be in the smallest unit of your currency. Example: 100 = $1.00USD [max value: 9999900] </dd>
* <dt><tt>memo</tt></dt> <dd>A memo that is displayed to the customer on the invoice payment screen. [max length: 4000] </dd>
* <dt><tt>name</tt></dt> <dd>The name of the customer we are invoicing. This is optional if customer or invoiceToCopy is provided. A new customer will be created using the the name and email. [max length: 50, min length: 2] </dd>
* <dt><tt>note</tt></dt> <dd>This field can be used to store a note that is not displayed to the customer. [max length: 4000] </dd>
* <dt><tt>payment</tt></dt> <dd>The ID of the payment. Use this ID to query the /payment API. [max length: 255] </dd>
* <dt><tt>reference</tt></dt> <dd>User defined reference field. [max length: 255] </dd>
* <dt><tt>shippingAddress.city</tt></dt> <dd>Address city of the location where the goods or services were supplied. [max length: 255, min length: 2] </dd>
* <dt><tt>shippingAddress.country</tt></dt> <dd>Address country of the location where the goods or services were supplied. [max length: 2, min length: 2] </dd>
* <dt><tt>shippingAddress.line1</tt></dt> <dd>Address line 1 of the location where the goods or services were supplied. [max length: 255] </dd>
* <dt><tt>shippingAddress.line2</tt></dt> <dd>Address line 2 of the location where the goods or services were supplied. [max length: 255] </dd>
* <dt><tt>shippingAddress.name</tt></dt> <dd>Address name of the location where the goods or services were supplied. [max length: 255] </dd>
* <dt><tt>shippingAddress.state</tt></dt> <dd>Address state of the location where the goods or services were supplied. [max length: 255] </dd>
* <dt><tt>shippingAddress.zip</tt></dt> <dd>Address zip of the location where the goods or services were supplied. [max length: 32] </dd>
* <dt><tt>status</tt></dt> <dd>New status of the invoice. </dd>
* <dt><tt>suppliedDate</tt></dt> <dd>The date on which the goods or services were supplied. </dd>
* <dt><tt>taxNo</tt></dt> <dd>The tax number or VAT id of the person who supplied the goods or services. [max length: 255] </dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return Invoice a Invoice object.
*/
public function updateInvoice($authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 1);
$object = Simplify_PaymentsApi::updateObject($this, $authentication);
return $object;
}
/**
* @ignore
*/
public function getClazz() {
return "Invoice";
}
}

View File

@@ -0,0 +1,128 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/*
* Copyright (c) 2013 - 2015 MasterCard International Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* Neither the name of the MasterCard International Incorporated nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
class Simplify_InvoiceItem extends Simplify_Object {
/**
* Creates an Simplify_InvoiceItem object
* @param array $hash a map of parameters; valid keys are:<dl style="padding-left:10px;">
* <dt><tt>amount</tt></dt> <dd>Amount of the invoice item in the smallest unit of your currency. Example: 100 = $1.00USD [min value: -9999900, max value: 9999900] <strong>required </strong></dd>
* <dt><tt>description</tt></dt> <dd>Individual items of an invoice [max length: 1024] </dd>
* <dt><tt>invoice</tt></dt> <dd>The ID of the invoice this item belongs to. </dd>
* <dt><tt>product</tt></dt> <dd>Product ID this item relates to. </dd>
* <dt><tt>quantity</tt></dt> <dd>Quantity of the item. This total amount of the invoice item is the amount * quantity. [min value: 1, max value: 999999, default: 1] </dd>
* <dt><tt>reference</tt></dt> <dd>User defined reference field. [max length: 255] </dd>
* <dt><tt>tax</tt></dt> <dd>The tax ID of the tax charge in the invoice item. </dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.<i/>
* @return InvoiceItem a InvoiceItem object.
*/
static public function createInvoiceItem($hash, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$instance = new Simplify_InvoiceItem();
$instance->setAll($hash);
$object = Simplify_PaymentsApi::createObject($instance, $authentication);
return $object;
}
/**
* Deletes an Simplify_InvoiceItem object.
*
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
*
* @return true
*/
public function deleteInvoiceItem($authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 1);
$obj = Simplify_PaymentsApi::deleteObject($this, $authentication);
$this->properties = null;
return true;
}
/**
* Retrieve a Simplify_InvoiceItem object from the API
*
* @param string id the id of the InvoiceItem object to retrieve
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return InvoiceItem a InvoiceItem object
*/
static public function findInvoiceItem($id, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_InvoiceItem();
$val->id = $id;
$obj = Simplify_PaymentsApi::findObject($val, $authentication);
return $obj;
}
/**
* Updates an Simplify_InvoiceItem object.
*
* The properties that can be updated:
* <dl style="padding-left:10px;">
* <dt><tt>amount</tt></dt> <dd>Amount of the invoice item in the smallest unit of your currency. Example: 100 = $1.00USD [min value: 1] </dd>
* <dt><tt>description</tt></dt> <dd>Individual items of an invoice </dd>
* <dt><tt>quantity</tt></dt> <dd>Quantity of the item. This total amount of the invoice item is the amount * quantity. [min value: 1, max value: 999999] </dd>
* <dt><tt>reference</tt></dt> <dd>User defined reference field. </dd>
* <dt><tt>tax</tt></dt> <dd>The tax ID of the tax charge in the invoice item. </dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return InvoiceItem a InvoiceItem object.
*/
public function updateInvoiceItem($authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 1);
$object = Simplify_PaymentsApi::updateObject($this, $authentication);
return $object;
}
/**
* @ignore
*/
public function getClazz() {
return "InvoiceItem";
}
}

View File

@@ -0,0 +1,90 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/*
* Copyright (c) 2013 - 2015 MasterCard International Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* Neither the name of the MasterCard International Incorporated nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* Base class for all domain objects.
*/
class Simplify_Object {
private $properties = array();
/**
* @ignore
*
* @param string $key
*
* @return mixed
*/
public function __get($key) {
if (array_key_exists($key, $this->properties)) {
return $this->properties[$key];
} else {
return null;
}
}
/**
* @ignore
*
* @param string $key
* @param mixed $value
*/
public function __set($key, $value) {
$this->properties[$key] = $value;
}
/**
* Updates the object's properties with the values in the specified map.
* @param $hash array Map of values to set.
*/
public function setAll($hash) {
foreach ($hash as $key => $value) {
$this->$key = $value;
}
}
/**
* @ignore
*/
public function __toString() {
return json_encode($this->properties);
}
/**
* Returns the object's properties as a map.
* @return array map of properties.
*/
public function getProperties() {
return $this->properties;
}
}

View File

@@ -0,0 +1,145 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/*
* Copyright (c) 2013 - 2015 MasterCard International Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* Neither the name of the MasterCard International Incorporated nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
class Simplify_Payment extends Simplify_Object {
/**
* Creates an Simplify_Payment object
* @param array $hash a map of parameters; valid keys are:<dl style="padding-left:10px;">
* <dt><tt>amount</tt></dt> <dd>Amount of the payment (in the smallest unit of your currency). Example: 100 = $1.00USD </dd>
* <dt><tt>authorization</tt></dt> <dd>The ID of the authorization being used to capture the payment. </dd>
* <dt><tt>card.addressCity</tt></dt> <dd>City of the cardholder. [max length: 50, min length: 2] </dd>
* <dt><tt>card.addressCountry</tt></dt> <dd>Country code (ISO-3166-1-alpha-2 code) of residence of the cardholder. [max length: 2, min length: 2] </dd>
* <dt><tt>card.addressLine1</tt></dt> <dd>Address of the cardholder. [max length: 255] </dd>
* <dt><tt>card.addressLine2</tt></dt> <dd>Address of the cardholder if needed. [max length: 255] </dd>
* <dt><tt>card.addressState</tt></dt> <dd>State of residence of the cardholder. For the US, this is a 2-digit USPS code. [max length: 255, min length: 2] </dd>
* <dt><tt>card.addressZip</tt></dt> <dd>Postal code of the cardholder. The postal code size is between 5 and 9 in length and only contain numbers or letters. [max length: 9, min length: 3] </dd>
* <dt><tt>card.cvc</tt></dt> <dd>CVC security code of the card. This is the code on the back of the card. Example: 123 </dd>
* <dt><tt>card.expMonth</tt></dt> <dd>Expiration month of the card. Format is MM. Example: January = 01 [min value: 1, max value: 12] <strong>required </strong></dd>
* <dt><tt>card.expYear</tt></dt> <dd>Expiration year of the card. Format is YY. Example: 2013 = 13 [min value: 0, max value: 99] <strong>required </strong></dd>
* <dt><tt>card.name</tt></dt> <dd>Name as it appears on the card. [max length: 50, min length: 2] </dd>
* <dt><tt>card.number</tt></dt> <dd>Card number as it appears on the card. [max length: 19, min length: 13] <strong>required </strong></dd>
* <dt><tt>currency</tt></dt> <dd>Currency code (ISO-4217) for the transaction. Must match the currency associated with your account. [default: USD] <strong>required </strong></dd>
* <dt><tt>customer</tt></dt> <dd>ID of customer. If specified, card on file of customer will be used. </dd>
* <dt><tt>description</tt></dt> <dd>Free form text field to be used as a description of the payment. This field is echoed back with the payment on any find or list operations. [max length: 1024] </dd>
* <dt><tt>invoice</tt></dt> <dd>ID of invoice for which this payment is being made. </dd>
* <dt><tt>reference</tt></dt> <dd>Custom reference field to be used with outside systems. </dd>
* <dt><tt>replayId</tt></dt> <dd>An identifier that can be sent to uniquely identify a payment request to facilitate retries due to I/O related issues. This identifier must be unique for your account (sandbox or live) across all of your payments. If supplied, we will check for a payment on your account that matches this identifier. If found will attempt to return an identical response of the original request. [max length: 50, min length: 1] </dd>
* <dt><tt>statementDescription.name</tt></dt> <dd>Merchant name. <strong>required </strong></dd>
* <dt><tt>statementDescription.phoneNumber</tt></dt> <dd>Merchant contact phone number. </dd>
* <dt><tt>token</tt></dt> <dd>If specified, card associated with card token will be used. [max length: 255] </dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.<i/>
* @return Payment a Payment object.
*/
static public function createPayment($hash, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$instance = new Simplify_Payment();
$instance->setAll($hash);
$object = Simplify_PaymentsApi::createObject($instance, $authentication);
return $object;
}
/**
* Retrieve Simplify_Payment objects.
* @param array criteria a map of parameters; valid keys are:<dl style="padding-left:10px;">
* <dt><tt>filter</tt></dt> <dd>Filters to apply to the list. </dd>
* <dt><tt>max</tt></dt> <dd>Allows up to a max of 50 list items to return. [min value: 0, max value: 50, default: 20] </dd>
* <dt><tt>offset</tt></dt> <dd>Used in paging of the list. This is the start offset of the page. [min value: 0, default: 0] </dd>
* <dt><tt>sorting</tt></dt> <dd>Allows for ascending or descending sorting of the list. The value maps properties to the sort direction (either <tt>asc</tt> for ascending or <tt>desc</tt> for descending). Sortable properties are: <tt> dateCreated</tt><tt> createdBy</tt><tt> amount</tt><tt> id</tt><tt> description</tt><tt> paymentDate</tt>.</dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return ResourceList a ResourceList object that holds the list of Payment objects and the total
* number of Payment objects available for the given criteria.
* @see ResourceList
*/
static public function listPayment($criteria = null, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_Payment();
$list = Simplify_PaymentsApi::listObject($val, $criteria, $authentication);
return $list;
}
/**
* Retrieve a Simplify_Payment object from the API
*
* @param string id the id of the Payment object to retrieve
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return Payment a Payment object
*/
static public function findPayment($id, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_Payment();
$val->id = $id;
$obj = Simplify_PaymentsApi::findObject($val, $authentication);
return $obj;
}
/**
* Updates an Simplify_Payment object.
*
* The properties that can be updated:
* <dl style="padding-left:10px;"></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return Payment a Payment object.
*/
public function updatePayment($authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 1);
$object = Simplify_PaymentsApi::updateObject($this, $authentication);
return $object;
}
/**
* @ignore
*/
public function getClazz() {
return "Payment";
}
}

View File

@@ -0,0 +1,358 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/*
* Copyright (c) 2013 - 2015 MasterCard International Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* Neither the name of the MasterCard International Incorporated nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
class Simplify_PaymentsApi
{
/**
* @ignore
*/
public static $methodMap = array(
'create' => 'POST',
'delete' => 'DELETE',
'list' => 'GET',
'show' => 'GET',
'update' => 'PUT'
);
/**
* @ignore
*
* @param object $object
* @param object $authentication
*
* @return mixed
*/
static public function createObject($object, $authentication = null)
{
$paymentsApi = new Simplify_PaymentsApi();
$jsonObject = $paymentsApi->execute("create", $object, $authentication);
$o = $paymentsApi->convertFromHashToObject($jsonObject, $object->getClazz());
return $o;
}
/**
* @ignore
*
* @param object $object
* @param object $authentication
*
* @return mixed
*/
static public function findObject($object, $authentication = null)
{
$paymentsApi = new Simplify_PaymentsApi();
$jsonObject = $paymentsApi->execute("show", $object, $authentication);
$o = $paymentsApi->convertFromHashToObject($jsonObject, $object->getClazz());
return $o;
}
/**
* @ignore
*
* @param object $object
* @param object $authentication
*
* @return mixed
*/
static public function updateObject($object, $authentication = null) {
$paymentsApi = new Simplify_PaymentsApi();
$jsonObject = $paymentsApi->execute("update", $object, $authentication);
$o = $paymentsApi->convertFromHashToObject($jsonObject, $object->getClazz());
return $o;
}
/**
* @ignore
*
* @param object $object
* @param object $authentication
*
* @return mixed
*/
static public function deleteObject($object, $authentication = null) {
$paymentsApi = new Simplify_PaymentsApi();
$jsonObject = $paymentsApi->execute("delete", $object, $authentication);
return $jsonObject;
}
/**
* @ignore
*
* @param object $object
* @param array $criteria
* @param object $authentication
*
* @return Simplify_ResourceList
*/
static public function listObject($object, $criteria = null, $authentication = null) {
if ($criteria != null) {
if (isset($criteria['max'])) {
$object->max = $criteria['max'];
}
if (isset($criteria['offset'])) {
$object->offset = $criteria['offset'];
}
if (isset($criteria['sorting'])) {
$object->sorting = $criteria['sorting'];
}
if (isset($criteria['filter'])) {
$object->filter = $criteria['filter'];
}
}
$paymentsApi = new Simplify_PaymentsApi();
$jsonObject = $paymentsApi->execute("list", $object, $authentication);
$ret = new Simplify_ResourceList();
if (array_key_exists('list', $jsonObject) & is_array($jsonObject['list'])) {
foreach ($jsonObject['list'] as $obj) {
array_push($ret->list, $paymentsApi->convertFromHashToObject($obj, $object->getClazz()));
}
$ret->total = $jsonObject['total'];
}
return $ret;
}
/**
* @ignore
*
* @param array $from
* @param string $toClazz
*
* @return mixed
*/
public function convertFromHashToObject($from, $toClazz)
{
$clazz = 'stdClass';
$toClazz = "Simplify_" . $toClazz;
if ("stdClass" != $toClazz && class_exists("{$toClazz}", false)) {
$clazz = "{$toClazz}";
}
$object = new $clazz();
foreach ($from as $key => $value) {
if (is_array($value) && count(array_keys($value))) {
$newClazz = "Simplify_" . ucfirst($key);
if (!class_exists($newClazz, false)) {
$newClazz = 'stdClass';
}
$object->$key = $this->convertFromHashToObject($value, $newClazz);
} else {
$object->$key = $value;
}
}
return $object;
}
/**
* @ignore
*
* @param string $publicKey
* @param string $action
* @param object $object
*
* @return string
*/
public function getUrl($publicKey, $action, $object)
{
$url = $this->fixUrl(Simplify::$apiBaseSandboxUrl);
if ($this->isLiveKey($publicKey)) {
$url = $this->fixUrl(Simplify::$apiBaseLiveUrl);
}
$url = $this->fixUrl($url) . urlencode(lcfirst($object->getClazz())) . '/';
$queryParams = array();
if ($action == "show") {
$url .= urlencode($object->id);
} elseif ($action == "list") {
$queryParams = array_merge($queryParams, array('max' => $object->max, 'offset' => $object->offset));
if (is_array($object->filter) && count(array_keys($object->filter))) {
foreach ($object->filter as $key => $value) {
$queryParams["filter[$key]"] = $value;
}
}
if (is_array($object->sorting) && count(array_keys($object->sorting))) {
foreach ($object->sorting as $key => $value) {
$queryParams["sorting[$key]"] = $value;
}
}
$query = http_build_query($queryParams);
if ($query != '') {
if (strpos($url, '?', strlen($url)) === false) $url .= '?';
$url .= $query;
}
} elseif ($action == "delete") {
$url .= urlencode($object->id);
} elseif ($action == "update") {
$url .= urlencode($object->id);
} elseif ($action == "create") {
}
return $url;
}
/**
* @ignore
*
* @param string $action
*
* @return string
*/
public function getMethod($action)
{
if (array_key_exists(strtolower($action), self::$methodMap)) {
return self::$methodMap[strtolower($action)];
}
return 'GET';
}
/**
* @ignore
*
* @param string $action
* @param object $object
* @param object $authentication
*
* @return mixed
*/
private function execute($action, $object, $authentication)
{
$http = new Simplify_HTTP();
return $http->apiRequest($this->getUrl($authentication->publicKey, $action, $object), $this->getMethod($action),
$authentication, json_encode($object->getProperties()));
}
/**
* @ignore
*
* @param string $hash
* @param object $authentication
*
* @return mixed
*/
public function jwsDecode($hash, $authentication)
{
$http = new Simplify_HTTP();
$data = $http->jwsDecode($authentication, $hash);
return json_decode($data, true);
}
/**
* @ignore
*
* @param string $url
*
* @return string
*/
private function fixUrl($url)
{
if ($this->endsWith($url, '/')) {
return $url;
}
return $url . '/';
}
/**
* @ignore
*
* @param string $k
*
* @return bool
*/
private function isLiveKey($k) {
return strpos($k, "lvpb") === 0;
}
/**
* @ignore
*
* @param string $s
* @param string $c
*
* @return bool
*/
private function endsWith($s, $c)
{
return substr($s, -strlen($c)) == $c;
}
/**
* Helper function to build the Authentication object for backwards compatibility.
* An array of all the arguments passed to one of the API functions is checked against what
* we expect to received. If it's greater, then we're assuming that the user is using the older way of
* passing the keys. i.e as two separate strings. We take those two string and create the Authentication object
*
* @ignore
* @param $authentication
* @param $args
* @param $expectedArgCount
* @return Simplify_Authentication
*/
static function buildAuthenticationObject($authentication = null, $args, $expectedArgCount){
if(sizeof($args) > $expectedArgCount) {
$authentication = new Simplify_Authentication($args[$expectedArgCount-1], $args[$expectedArgCount]);
}
if ($authentication == null){
$authentication = new Simplify_Authentication();
}
// check that the keys have been set, if not use the global keys
if ( empty($authentication->publicKey)){
$authentication->publicKey = Simplify::$publicKey;
}
if ( empty($authentication->privateKey)){
$authentication->privateKey = Simplify::$privateKey;
}
return $authentication;
}
}

View File

@@ -0,0 +1,151 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/*
* Copyright (c) 2013 - 2015 MasterCard International Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* Neither the name of the MasterCard International Incorporated nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
class Simplify_Plan extends Simplify_Object {
/**
* Creates an Simplify_Plan object
* @param array $hash a map of parameters; valid keys are:<dl style="padding-left:10px;">
* <dt><tt>amount</tt></dt> <dd>Amount of payment for the plan in the smallest unit of your currency. Example: 100 = $1.00USD <strong>required </strong></dd>
* <dt><tt>billingCycle</tt></dt> <dd>How the plan is billed to the customer. Values must be AUTO (indefinitely until the customer cancels) or FIXED (a fixed number of billing cycles). [default: AUTO] </dd>
* <dt><tt>billingCycleLimit</tt></dt> <dd>The number of fixed billing cycles for a plan. Only used if the billingCycle parameter is set to FIXED. Example: 4 </dd>
* <dt><tt>currency</tt></dt> <dd>Currency code (ISO-4217) for the plan. Must match the currency associated with your account. [default: USD] <strong>required </strong></dd>
* <dt><tt>frequency</tt></dt> <dd>Frequency of payment for the plan. Used in conjunction with frequencyPeriod. Valid values are "DAILY", "WEEKLY", "MONTHLY" and "YEARLY". [default: MONTHLY] <strong>required </strong></dd>
* <dt><tt>frequencyPeriod</tt></dt> <dd>Period of frequency of payment for the plan. Example: if the frequency is weekly, and periodFrequency is 2, then the subscription is billed bi-weekly. [min value: 1, default: 1] <strong>required </strong></dd>
* <dt><tt>name</tt></dt> <dd>Name of the plan [max length: 50, min length: 2] <strong>required </strong></dd>
* <dt><tt>renewalReminderLeadDays</tt></dt> <dd>If set, how many days before the next billing cycle that a renewal reminder is sent to the customer. If null, then no emails are sent. Minimum value is 7 if set. </dd>
* <dt><tt>trialPeriod</tt></dt> <dd>Plan free trial period selection. Must be Days, Weeks, or Month [default: NONE] <strong>required </strong></dd>
* <dt><tt>trialPeriodQuantity</tt></dt> <dd>Quantity of the trial period. Must be greater than 0 and a whole number. [min value: 1] </dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.<i/>
* @return Plan a Plan object.
*/
static public function createPlan($hash, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$instance = new Simplify_Plan();
$instance->setAll($hash);
$object = Simplify_PaymentsApi::createObject($instance, $authentication);
return $object;
}
/**
* Deletes an Simplify_Plan object.
*
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
*
* @return true
*/
public function deletePlan($authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 1);
$obj = Simplify_PaymentsApi::deleteObject($this, $authentication);
$this->properties = null;
return true;
}
/**
* Retrieve Simplify_Plan objects.
* @param array criteria a map of parameters; valid keys are:<dl style="padding-left:10px;">
* <dt><tt>filter</tt></dt> <dd>Filters to apply to the list. </dd>
* <dt><tt>max</tt></dt> <dd>Allows up to a max of 50 list items to return. [min value: 0, max value: 50, default: 20] </dd>
* <dt><tt>offset</tt></dt> <dd>Used in paging of the list. This is the start offset of the page. [min value: 0, default: 0] </dd>
* <dt><tt>sorting</tt></dt> <dd>Allows for ascending or descending sorting of the list. The value maps properties to the sort direction (either <tt>asc</tt> for ascending or <tt>desc</tt> for descending). Sortable properties are: <tt> dateCreated</tt><tt> amount</tt><tt> frequency</tt><tt> name</tt><tt> id</tt>.</dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return ResourceList a ResourceList object that holds the list of Plan objects and the total
* number of Plan objects available for the given criteria.
* @see ResourceList
*/
static public function listPlan($criteria = null, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_Plan();
$list = Simplify_PaymentsApi::listObject($val, $criteria, $authentication);
return $list;
}
/**
* Retrieve a Simplify_Plan object from the API
*
* @param string id the id of the Plan object to retrieve
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return Plan a Plan object
*/
static public function findPlan($id, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_Plan();
$val->id = $id;
$obj = Simplify_PaymentsApi::findObject($val, $authentication);
return $obj;
}
/**
* Updates an Simplify_Plan object.
*
* The properties that can be updated:
* <dl style="padding-left:10px;">
* <dt><tt>name</tt></dt> <dd>Name of the plan. [min length: 2] <strong>required </strong></dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return Plan a Plan object.
*/
public function updatePlan($authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 1);
$object = Simplify_PaymentsApi::updateObject($this, $authentication);
return $object;
}
/**
* @ignore
*/
public function getClazz() {
return "Plan";
}
}

View File

@@ -0,0 +1,112 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/*
* Copyright (c) 2013 - 2015 MasterCard International Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* Neither the name of the MasterCard International Incorporated nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
class Simplify_Refund extends Simplify_Object {
/**
* Creates an Simplify_Refund object
* @param array $hash a map of parameters; valid keys are:<dl style="padding-left:10px;">
* <dt><tt>amount</tt></dt> <dd>Amount of the refund in the smallest unit of your currency. Example: 100 = $1.00USD [min value: 1] <strong>required </strong></dd>
* <dt><tt>payment</tt></dt> <dd>ID of the payment for the refund <strong>required </strong></dd>
* <dt><tt>reason</tt></dt> <dd>Reason for the refund </dd>
* <dt><tt>reference</tt></dt> <dd>Custom reference field to be used with outside systems. </dd>
* <dt><tt>replayId</tt></dt> <dd>An identifier that can be sent to uniquely identify a refund request to facilitate retries due to I/O related issues. This identifier must be unique for your account (sandbox or live) across all of your refunds. If supplied, we will check for a refund on your account that matches this identifier. If found we will return an identical response to that of the original request. [max length: 50, min length: 1] </dd>
* <dt><tt>statementDescription.name</tt></dt> <dd>Merchant name. <strong>required </strong></dd>
* <dt><tt>statementDescription.phoneNumber</tt></dt> <dd>Merchant contact phone number. </dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.<i/>
* @return Refund a Refund object.
*/
static public function createRefund($hash, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$instance = new Simplify_Refund();
$instance->setAll($hash);
$object = Simplify_PaymentsApi::createObject($instance, $authentication);
return $object;
}
/**
* Retrieve Simplify_Refund objects.
* @param array criteria a map of parameters; valid keys are:<dl style="padding-left:10px;">
* <dt><tt>filter</tt></dt> <dd>Filters to apply to the list. </dd>
* <dt><tt>max</tt></dt> <dd>Allows up to a max of 50 list items to return. [min value: 0, max value: 50, default: 20] </dd>
* <dt><tt>offset</tt></dt> <dd>Used in paging of the list. This is the start offset of the page. [min value: 0, default: 0] </dd>
* <dt><tt>sorting</tt></dt> <dd>Allows for ascending or descending sorting of the list. The value maps properties to the sort direction (either <tt>asc</tt> for ascending or <tt>desc</tt> for descending). Sortable properties are: <tt> id</tt><tt> amount</tt><tt> description</tt><tt> dateCreated</tt><tt> paymentDate</tt>.</dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return ResourceList a ResourceList object that holds the list of Refund objects and the total
* number of Refund objects available for the given criteria.
* @see ResourceList
*/
static public function listRefund($criteria = null, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_Refund();
$list = Simplify_PaymentsApi::listObject($val, $criteria, $authentication);
return $list;
}
/**
* Retrieve a Simplify_Refund object from the API
*
* @param string id the id of the Refund object to retrieve
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return Refund a Refund object
*/
static public function findRefund($id, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_Refund();
$val->id = $id;
$obj = Simplify_PaymentsApi::findObject($val, $authentication);
return $obj;
}
/**
* @ignore
*/
public function getClazz() {
return "Refund";
}
}

View File

@@ -0,0 +1,48 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/*
* Copyright (c) 2013 - 2015 MasterCard International Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* Neither the name of the MasterCard International Incorporated nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* Class Simplify_ResourceList represents a collection of domain objects returned by one of the list<Domain>() methods.
*/
class Simplify_ResourceList {
/**
* @var array $list the list of domain objects.
*/
public $list = array();
/**
* @var int $total the total number of object available.
*/
public $total = 0;
}

View File

@@ -0,0 +1,164 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/*
* Copyright (c) 2013 - 2015 MasterCard International Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* Neither the name of the MasterCard International Incorporated nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
class Simplify_Subscription extends Simplify_Object {
/**
* Creates an Simplify_Subscription object
* @param array $hash a map of parameters; valid keys are:<dl style="padding-left:10px;">
* <dt><tt>amount</tt></dt> <dd>Amount of the payment in the smallest unit of your currency. Example: 100 = $1.00USD </dd>
* <dt><tt>billingCycle</tt></dt> <dd>How the plan is billed to the customer. Values must be AUTO (indefinitely until the customer cancels) or FIXED (a fixed number of billing cycles). [default: AUTO] </dd>
* <dt><tt>billingCycleLimit</tt></dt> <dd>The number of fixed billing cycles for a plan. Only used if the billingCycle parameter is set to FIXED. Example: 4 </dd>
* <dt><tt>coupon</tt></dt> <dd>Coupon ID associated with the subscription </dd>
* <dt><tt>currency</tt></dt> <dd>Currency code (ISO-4217). Must match the currency associated with your account. [default: USD] </dd>
* <dt><tt>customer</tt></dt> <dd>Customer that is enrolling in the subscription. </dd>
* <dt><tt>frequency</tt></dt> <dd>Frequency of payment for the plan. Used in conjunction with frequencyPeriod. Valid values are "DAILY", "WEEKLY", "MONTHLY" and "YEARLY". </dd>
* <dt><tt>frequencyPeriod</tt></dt> <dd>Period of frequency of payment for the plan. Example: if the frequency is weekly, and periodFrequency is 2, then the subscription is billed bi-weekly. </dd>
* <dt><tt>name</tt></dt> <dd>Name describing subscription </dd>
* <dt><tt>plan</tt></dt> <dd>The ID of the plan that should be used for the subscription. </dd>
* <dt><tt>quantity</tt></dt> <dd>Quantity of the plan for the subscription. [min value: 1] </dd>
* <dt><tt>renewalReminderLeadDays</tt></dt> <dd>If set, how many days before the next billing cycle that a renewal reminder is sent to the customer. If null, then no emails are sent. Minimum value is 7 if set. </dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.<i/>
* @return Subscription a Subscription object.
*/
static public function createSubscription($hash, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$instance = new Simplify_Subscription();
$instance->setAll($hash);
$object = Simplify_PaymentsApi::createObject($instance, $authentication);
return $object;
}
/**
* Deletes an Simplify_Subscription object.
*
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
*
* @return true
*/
public function deleteSubscription($authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 1);
$obj = Simplify_PaymentsApi::deleteObject($this, $authentication);
$this->properties = null;
return true;
}
/**
* Retrieve Simplify_Subscription objects.
* @param array criteria a map of parameters; valid keys are:<dl style="padding-left:10px;">
* <dt><tt>filter</tt></dt> <dd>Filters to apply to the list. </dd>
* <dt><tt>max</tt></dt> <dd>Allows up to a max of 50 list items to return. [min value: 0, max value: 50, default: 20] </dd>
* <dt><tt>offset</tt></dt> <dd>Used in paging of the list. This is the start offset of the page. [min value: 0, default: 0] </dd>
* <dt><tt>sorting</tt></dt> <dd>Allows for ascending or descending sorting of the list. The value maps properties to the sort direction (either <tt>asc</tt> for ascending or <tt>desc</tt> for descending). Sortable properties are: <tt> id</tt><tt> plan</tt>.</dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return ResourceList a ResourceList object that holds the list of Subscription objects and the total
* number of Subscription objects available for the given criteria.
* @see ResourceList
*/
static public function listSubscription($criteria = null, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_Subscription();
$list = Simplify_PaymentsApi::listObject($val, $criteria, $authentication);
return $list;
}
/**
* Retrieve a Simplify_Subscription object from the API
*
* @param string id the id of the Subscription object to retrieve
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return Subscription a Subscription object
*/
static public function findSubscription($id, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_Subscription();
$val->id = $id;
$obj = Simplify_PaymentsApi::findObject($val, $authentication);
return $obj;
}
/**
* Updates an Simplify_Subscription object.
*
* The properties that can be updated:
* <dl style="padding-left:10px;">
* <dt><tt>amount</tt></dt> <dd>Amount of the payment in the smallest unit of your currency. Example: 100 = $1.00USD </dd>
* <dt><tt>billingCycle</tt></dt> <dd>How the plan is billed to the customer. Values must be AUTO (indefinitely until the customer cancels) or FIXED (a fixed number of billing cycles). [default: AUTO] </dd>
* <dt><tt>billingCycleLimit</tt></dt> <dd>The number of fixed billing cycles for a plan. Only used if the billingCycle parameter is set to FIXED. Example: 4 </dd>
* <dt><tt>coupon</tt></dt> <dd>Coupon being assigned to this subscription </dd>
* <dt><tt>currency</tt></dt> <dd>Currency code (ISO-4217). Must match the currency associated with your account. [default: USD] </dd>
* <dt><tt>frequency</tt></dt> <dd>Frequency of payment for the plan. Used in conjunction with frequencyPeriod. Valid values are "DAILY", "WEEKLY", "MONTHLY" and "YEARLY". </dd>
* <dt><tt>frequencyPeriod</tt></dt> <dd>Period of frequency of payment for the plan. Example: if the frequency is weekly, and periodFrequency is 2, then the subscription is billed bi-weekly. [min value: 1] </dd>
* <dt><tt>name</tt></dt> <dd>Name describing subscription </dd>
* <dt><tt>plan</tt></dt> <dd>Plan that should be used for the subscription. </dd>
* <dt><tt>prorate</tt></dt> <dd>Whether to prorate existing subscription. [default: true] <strong>required </strong></dd>
* <dt><tt>quantity</tt></dt> <dd>Quantity of the plan for the subscription. [min value: 1] </dd>
* <dt><tt>renewalReminderLeadDays</tt></dt> <dd>If set, how many days before the next billing cycle that a renewal reminder is sent to the customer. If null or 0, no emails are sent. Minimum value is 7 if set. </dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return Subscription a Subscription object.
*/
public function updateSubscription($authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 1);
$object = Simplify_PaymentsApi::updateObject($this, $authentication);
return $object;
}
/**
* @ignore
*/
public function getClazz() {
return "Subscription";
}
}

View File

@@ -0,0 +1,124 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/*
* Copyright (c) 2013 - 2015 MasterCard International Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* Neither the name of the MasterCard International Incorporated nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
class Simplify_Tax extends Simplify_Object {
/**
* Creates an Simplify_Tax object
* @param array $hash a map of parameters; valid keys are:<dl style="padding-left:10px;">
* <dt><tt>label</tt></dt> <dd>The label of the tax object. [max length: 255] <strong>required </strong></dd>
* <dt><tt>rate</tt></dt> <dd>The tax rate. Decimal value up three decimal places. e.g 12.501. [max length: 6] <strong>required </strong></dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.<i/>
* @return Tax a Tax object.
*/
static public function createTax($hash, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$instance = new Simplify_Tax();
$instance->setAll($hash);
$object = Simplify_PaymentsApi::createObject($instance, $authentication);
return $object;
}
/**
* Deletes an Simplify_Tax object.
*
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
*
* @return true
*/
public function deleteTax($authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 1);
$obj = Simplify_PaymentsApi::deleteObject($this, $authentication);
$this->properties = null;
return true;
}
/**
* Retrieve Simplify_Tax objects.
* @param array criteria a map of parameters; valid keys are:<dl style="padding-left:10px;">
* <dt><tt>filter</tt></dt> <dd>Filters to apply to the list. </dd>
* <dt><tt>max</tt></dt> <dd>Allows up to a max of 50 list items to return. [min value: 0, max value: 50, default: 20] </dd>
* <dt><tt>offset</tt></dt> <dd>Used in paging of the list. This is the start offset of the page. [min value: 0, default: 0] </dd>
* <dt><tt>sorting</tt></dt> <dd>Allows for ascending or descending sorting of the list. The value maps properties to the sort direction (either <tt>asc</tt> for ascending or <tt>desc</tt> for descending). Sortable properties are: <tt> id</tt><tt> label</tt>.</dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return ResourceList a ResourceList object that holds the list of Tax objects and the total
* number of Tax objects available for the given criteria.
* @see ResourceList
*/
static public function listTax($criteria = null, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_Tax();
$list = Simplify_PaymentsApi::listObject($val, $criteria, $authentication);
return $list;
}
/**
* Retrieve a Simplify_Tax object from the API
*
* @param string id the id of the Tax object to retrieve
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return Tax a Tax object
*/
static public function findTax($id, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_Tax();
$val->id = $id;
$obj = Simplify_PaymentsApi::findObject($val, $authentication);
return $obj;
}
/**
* @ignore
*/
public function getClazz() {
return "Tax";
}
}

View File

@@ -0,0 +1,141 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/*
* Copyright (c) 2013 - 2015 MasterCard International Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* Neither the name of the MasterCard International Incorporated nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
class Simplify_TransactionReview extends Simplify_Object {
/**
* Creates an Simplify_TransactionReview object
* @param array $hash a map of parameters; valid keys are:<dl style="padding-left:10px;"></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.<i/>
* @return TransactionReview a TransactionReview object.
*/
static public function createTransactionReview($hash, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$instance = new Simplify_TransactionReview();
$instance->setAll($hash);
$object = Simplify_PaymentsApi::createObject($instance, $authentication);
return $object;
}
/**
* Deletes an Simplify_TransactionReview object.
*
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
*
* @return true
*/
public function deleteTransactionReview($authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 1);
$obj = Simplify_PaymentsApi::deleteObject($this, $authentication);
$this->properties = null;
return true;
}
/**
* Retrieve Simplify_TransactionReview objects.
* @param array criteria a map of parameters; valid keys are:<dl style="padding-left:10px;">
* <dt><tt>filter</tt></dt> <dd>Allows for ascending or descending sorting of the list. </dd>
* <dt><tt>max</tt></dt> <dd>Allows up to a max of 50 list items to return. [min value: 0, max value: 50, default: 20] </dd>
* <dt><tt>offset</tt></dt> <dd>Filters to apply to the list. [min value: 0, default: 0] </dd>
* <dt><tt>sorting</tt></dt> <dd>Used in paging of the list. This is the start offset of the page. The value maps properties to the sort direction (either <tt>asc</tt> for ascending or <tt>desc</tt> for descending). Sortable properties are: <tt> dateCreated</tt><tt> status</tt>.</dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return ResourceList a ResourceList object that holds the list of TransactionReview objects and the total
* number of TransactionReview objects available for the given criteria.
* @see ResourceList
*/
static public function listTransactionReview($criteria = null, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_TransactionReview();
$list = Simplify_PaymentsApi::listObject($val, $criteria, $authentication);
return $list;
}
/**
* Retrieve a Simplify_TransactionReview object from the API
*
* @param string id the id of the TransactionReview object to retrieve
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return TransactionReview a TransactionReview object
*/
static public function findTransactionReview($id, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_TransactionReview();
$val->id = $id;
$obj = Simplify_PaymentsApi::findObject($val, $authentication);
return $obj;
}
/**
* Updates an Simplify_TransactionReview object.
*
* The properties that can be updated:
* <dl style="padding-left:10px;">
* <dt><tt>status</tt></dt> <dd>Status of the transaction review. </dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return TransactionReview a TransactionReview object.
*/
public function updateTransactionReview($authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 1);
$object = Simplify_PaymentsApi::updateObject($this, $authentication);
return $object;
}
/**
* @ignore
*/
public function getClazz() {
return "TransactionReview";
}
}

View File

@@ -0,0 +1,142 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/*
* Copyright (c) 2013 - 2015 MasterCard International Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* Neither the name of the MasterCard International Incorporated nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
class Simplify_Webhook extends Simplify_Object {
/**
* Creates an Simplify_Webhook object
* @param array $hash a map of parameters; valid keys are:<dl style="padding-left:10px;">
* <dt><tt>url</tt></dt> <dd>Endpoint URL <strong>required </strong></dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.<i/>
* @return Webhook a Webhook object.
*/
static public function createWebhook($hash, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$instance = new Simplify_Webhook();
$instance->setAll($hash);
$object = Simplify_PaymentsApi::createObject($instance, $authentication);
return $object;
}
/**
* Deletes an Simplify_Webhook object.
*
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
*
* @return true
*/
public function deleteWebhook($authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 1);
$obj = Simplify_PaymentsApi::deleteObject($this, $authentication);
$this->properties = null;
return true;
}
/**
* Retrieve Simplify_Webhook objects.
* @param array criteria a map of parameters; valid keys are:<dl style="padding-left:10px;">
* <dt><tt>filter</tt></dt> <dd>Filters to apply to the list. </dd>
* <dt><tt>max</tt></dt> <dd>Allows up to a max of 50 list items to return. [min value: 0, max value: 50, default: 20] </dd>
* <dt><tt>offset</tt></dt> <dd>Used in paging of the list. This is the start offset of the page. [min value: 0, default: 0] </dd>
* <dt><tt>sorting</tt></dt> <dd>Allows for ascending or descending sorting of the list. The value maps properties to the sort direction (either <tt>asc</tt> for ascending or <tt>desc</tt> for descending). Sortable properties are: <tt> dateCreated</tt>.</dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return ResourceList a ResourceList object that holds the list of Webhook objects and the total
* number of Webhook objects available for the given criteria.
* @see ResourceList
*/
static public function listWebhook($criteria = null, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_Webhook();
$list = Simplify_PaymentsApi::listObject($val, $criteria, $authentication);
return $list;
}
/**
* Retrieve a Simplify_Webhook object from the API
*
* @param string id the id of the Webhook object to retrieve
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return Webhook a Webhook object
*/
static public function findWebhook($id, $authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 2);
$val = new Simplify_Webhook();
$val->id = $id;
$obj = Simplify_PaymentsApi::findObject($val, $authentication);
return $obj;
}
/**
* Updates an Simplify_Webhook object.
*
* The properties that can be updated:
* <dl style="padding-left:10px;">
* <dt><tt>url</tt></dt> <dd>Endpoint URL <strong>required </strong></dd></dl>
* @param $authentication - information used for the API call. If no value is passed the global keys Simplify::public_key and Simplify::private_key are used. <i>For backwards compatibility the public and private keys may be passed instead of the authentication object.</i>
* @return Webhook a Webhook object.
*/
public function updateWebhook($authentication = null) {
$args = func_get_args();
$authentication = Simplify_PaymentsApi::buildAuthenticationObject($authentication, $args, 1);
$object = Simplify_PaymentsApi::updateObject($this, $authentication);
return $object;
}
/**
* @ignore
*/
public function getClazz() {
return "Webhook";
}
}