Created
March 15, 2024 04:43
-
-
Save luiseduardobraschi/a82291ef481c695b91b593a9a4b80fdd to your computer and use it in GitHub Desktop.
Atualização de status plugin Pagar.me - Cláudio Sanches
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Pagar.me API | |
* | |
* @package WooCommerce_Pagarme/API | |
*/ | |
if ( ! defined( 'ABSPATH' ) ) { | |
exit; | |
} | |
/** | |
* WC_Pagarme_API class. | |
*/ | |
class WC_Pagarme_API { | |
/** | |
* API URL. | |
*/ | |
const API_URL = 'https://api.pagar.me/1/'; | |
/** | |
* Gateway class. | |
* | |
* @var WC_Payment_Gateway | |
*/ | |
protected $gateway; | |
/** | |
* API URL. | |
* | |
* @var string | |
*/ | |
protected $api_url = 'https://api.pagar.me/1/'; | |
/** | |
* JS Library URL. | |
* | |
* @var string | |
*/ | |
protected $js_url = 'https://assets.pagar.me/js/pagarme.min.js'; | |
/** | |
* Checkout JS Library URL. | |
* | |
* @var string | |
*/ | |
protected $checkout_js_url = 'https://assets.pagar.me/checkout/checkout.js'; | |
/** | |
* Constructor. | |
* | |
* @param WC_Payment_Gateway $gateway Gateway instance. | |
*/ | |
public function __construct( $gateway = null ) { | |
$this->gateway = $gateway; | |
} | |
/** | |
* Get API URL. | |
* | |
* @return string | |
*/ | |
public function get_api_url() { | |
return $this->api_url; | |
} | |
/** | |
* Get JS Library URL. | |
* | |
* @return string | |
*/ | |
public function get_js_url() { | |
return $this->js_url; | |
} | |
/** | |
* Get Checkout JS Library URL. | |
* | |
* @return string | |
*/ | |
public function get_checkout_js_url() { | |
return $this->checkout_js_url; | |
} | |
/** | |
* Returns a bool that indicates if currency is amongst the supported ones. | |
* | |
* @return bool | |
*/ | |
public function using_supported_currency() { | |
return 'BRL' === get_woocommerce_currency(); | |
} | |
/** | |
* Only numbers. | |
* | |
* @param string|int $string String to convert. | |
* | |
* @return string|int | |
*/ | |
protected function only_numbers( $string ) { | |
return preg_replace( '([^0-9])', '', $string ); | |
} | |
/** | |
* Get the smallest installment amount. | |
* | |
* @return int | |
*/ | |
public function get_smallest_installment() { | |
return ( 5 > $this->gateway->smallest_installment ) ? 500 : wc_format_decimal( $this->gateway->smallest_installment ) * 100; | |
} | |
/** | |
* Get the interest rate. | |
* | |
* @return float | |
*/ | |
public function get_interest_rate() { | |
return wc_format_decimal( $this->gateway->interest_rate ); | |
} | |
/** | |
* Do requests in the Pagar.me API. | |
* | |
* @param string $endpoint API Endpoint. | |
* @param string $method Request method. | |
* @param array $data Request data. | |
* @param array $headers Request headers. | |
* | |
* @return array Request response. | |
*/ | |
protected function do_request( $endpoint, $method = 'POST', $data = array(), $headers = array() ) { | |
$params = array( | |
'method' => $method, | |
'timeout' => 60, | |
); | |
if ( ! empty( $data ) ) { | |
$params['body'] = $data; | |
} | |
// Pagar.me user-agent and api version. | |
$x_pagarme_useragent = 'pagarme-woocommerce/' . WC_Pagarme::VERSION; | |
if ( defined( 'WC_VERSION' ) ) { | |
$x_pagarme_useragent .= ' woocommerce/' . WC_VERSION; | |
} | |
$x_pagarme_useragent .= ' wordpress/' . get_bloginfo( 'version' ); | |
$x_pagarme_useragent .= ' php/' . phpversion(); | |
$params['headers'] = [ | |
'User-Agent' => $x_pagarme_useragent, | |
'X-PagarMe-User-Agent' => $x_pagarme_useragent, | |
'X-PagarMe-Version' => '2017-07-17', | |
]; | |
if ( ! empty( $headers ) ) { | |
$params['headers'] = array_merge( $params['headers'], $headers ); | |
} | |
return wp_safe_remote_post( $this->get_api_url() . $endpoint, $params ); | |
} | |
/** | |
* Get the installments. | |
* | |
* @param float $amount Order amount. | |
* | |
* @return array | |
*/ | |
public function get_installments( $amount ) { | |
// Set the installment data. | |
$data = array( | |
'encryption_key' => $this->gateway->encryption_key, | |
'amount' => $amount * 100, | |
'interest_rate' => $this->get_interest_rate(), | |
'max_installments' => $this->gateway->max_installment, | |
'free_installments' => $this->gateway->free_installments, | |
); | |
$transient_id = 'pgi_' . md5( http_build_query( $data ) ); | |
// Get saved installment data. | |
$_installments = get_transient( $transient_id ); | |
if ( false !== $_installments ) { | |
return $_installments; | |
} | |
if ( 'yes' === $this->gateway->debug ) { | |
$this->gateway->log->add( $this->gateway->id, 'Getting the order installments...' ); | |
} | |
$response = $this->do_request( 'transactions/calculate_installments_amount', 'GET', $data ); | |
if ( is_wp_error( $response ) ) { | |
if ( 'yes' === $this->gateway->debug ) { | |
$this->gateway->log->add( $this->gateway->id, 'WP_Error in getting the installments: ' . $response->get_error_message() ); | |
} | |
return array(); | |
} else { | |
$_installments = json_decode( $response['body'], true ); | |
if ( isset( $_installments['installments'] ) ) { | |
$installments = $_installments['installments']; | |
if ( 'yes' === $this->gateway->debug ) { | |
$this->gateway->log->add( $this->gateway->id, 'Installments generated successfully: ' . print_r( $_installments, true ) ); | |
} | |
set_transient( $transient_id, $installments, MINUTE_IN_SECONDS * 5 ); | |
return $installments; | |
} | |
} | |
if ( 'yes' === $this->gateway->debug ) { | |
$this->gateway->log->add( $this->gateway->id, 'Failed to get the installments: ' . print_r( $response, true ) ); | |
} | |
return array(); | |
} | |
/** | |
* Get max installment. | |
* | |
* @param float $amount Order amount. | |
* | |
* @return int | |
*/ | |
public function get_max_installment( $amount ) { | |
$installments = $this->get_installments( $amount ); | |
$smallest_installment = $this->get_smallest_installment(); | |
$max = 1; | |
foreach ( $installments as $number => $installment ) { | |
if ( $smallest_installment > $installment['installment_amount'] ) { | |
break; | |
} | |
$max = $number; | |
} | |
return $max; | |
} | |
/** | |
* Generate the transaction data. | |
* | |
* @param WC_Order $order Order data. | |
* @param array $posted Form posted data. | |
* | |
* @return array Transaction data. | |
*/ | |
public function generate_transaction_data( $order, $posted ) { | |
// Set the request data. | |
$data = array( | |
'api_key' => $this->gateway->api_key, | |
'amount' => $order->get_total() * 100, | |
'postback_url' => WC()->api_request_url( get_class( $this->gateway ) ), | |
'customer' => array( | |
'name' => trim( $order->get_billing_first_name() . ' ' . $order->get_billing_last_name() ), | |
'email' => $order->get_billing_email(), | |
), | |
'metadata' => array( | |
'order_number' => $order->get_order_number(), | |
), | |
); | |
// Phone. | |
if ( ! empty( $order->get_billing_phone() ) ) { | |
$phone = $this->only_numbers( $order->get_billing_phone() ); | |
$data['customer']['phone'] = array( | |
'ddd' => substr( $phone, 0, 2 ), | |
'number' => substr( $phone, 2 ), | |
); | |
} | |
// Address. | |
if ( ! empty( $order->get_billing_address_1() ) ) { | |
$data['customer']['address'] = array( | |
'street' => $order->get_billing_address_1(), | |
'complementary' => $order->get_billing_address_2(), | |
'zipcode' => $this->only_numbers( $order->get_billing_postcode() ), | |
); | |
// Non-WooCommerce default address fields. | |
if ( ! empty( $order->get_meta( '_billing_number' ) ) ) { | |
$data['customer']['address']['street_number'] = $order->get_meta( '_billing_number' ); | |
} | |
if ( ! empty( $order->get_meta( '_billing_neighborhood' ) ) ) { | |
$data['customer']['address']['neighborhood'] = $order->get_meta( '_billing_neighborhood' ); | |
} | |
} | |
// Set the document number. | |
if ( class_exists( 'Extra_Checkout_Fields_For_Brazil' ) ) { | |
$wcbcf_settings = get_option( 'wcbcf_settings' ); | |
$person_type = (string) $wcbcf_settings['person_type']; | |
if ( '0' !== $person_type ) { | |
if ( ( '1' === $person_type && '1' === $order->get_meta( '_billing_persontype' ) ) || '2' === $person_type ) { | |
$data['customer']['document_number'] = $this->only_numbers( $order->get_meta( '_billing_cpf' ) ); | |
} | |
if ( ( '1' === $person_type && '2' === $order->get_meta( '_billing_persontype' ) ) || '3' === $person_type ) { | |
$data['customer']['name'] = $order->get_billing_company(); | |
$data['customer']['document_number'] = $this->only_numbers( $order->get_meta( '_billing_cnpj' ) ); | |
} | |
} | |
} else { | |
if ( ! empty( $order->get_meta( '_billing_cpf' ) ) ) { | |
$data['customer']['document_number'] = $this->only_numbers( $order->get_meta( '_billing_cpf' ) ); | |
} | |
if ( ! empty( $order->get_meta( '_billing_cnpj' ) ) ) { | |
$data['customer']['name'] = $order->get_billing_company(); | |
$data['customer']['document_number'] = $this->only_numbers( $order->get_meta( '_billing_cnpj' ) ); | |
} | |
} | |
// Set the customer gender. | |
if ( ! empty( $order->get_meta( '_billing_sex' ) ) ) { | |
$data['customer']['sex'] = strtoupper( substr( $order->get_meta( '_billing_sex' ), 0, 1 ) ); | |
} | |
// Set the customer birthdate. | |
if ( ! empty( $order->get_meta( '_billing__billing_birthdate' ) ) ) { | |
$birthdate = explode( '/', $order->get_meta( '_billing__billing_birthdate' ) ); | |
$data['customer']['born_at'] = $birthdate[1] . '-' . $birthdate[0] . '-' . $birthdate[2]; | |
} | |
if ( 'pagarme-credit-card' === $this->gateway->id ) { | |
if ( isset( $posted['pagarme_card_hash'] ) ) { | |
$data['payment_method'] = 'credit_card'; | |
$data['card_hash'] = $posted['pagarme_card_hash']; | |
} | |
$is_checkout_pagarme = isset( $this->gateway->checkout ) && 'yes' === $this->gateway->checkout; | |
$has_installment_data = ! empty( $posted['pagarme_installments'] ) && isset( $posted['pagarme_installments'] ); | |
$should_set_default_installment = $is_checkout_pagarme && ! $has_installment_data; | |
$_installment = $should_set_default_installment ? 1 : $posted['pagarme_installments']; | |
// Validate the installments. | |
$data['installments'] = $_installment; | |
// Get installments data. | |
$installments = $this->get_installments( $order->get_total() ); | |
if ( isset( $installments[ $_installment ] ) ) { | |
$installment = $installments[ $_installment ]; | |
$smallest_installment = $this->get_smallest_installment(); | |
if ( $installment['installment'] <= $this->gateway->max_installment && $smallest_installment <= $installment['installment_amount'] ) { | |
$data['amount'] = $installment['amount']; | |
} | |
} | |
} elseif ( 'pagarme-banking-ticket' === $this->gateway->id ) { | |
$data['payment_method'] = 'boleto'; | |
$data['async'] = 'yes' === $this->gateway->async; | |
} | |
// Add filter for Third Party plugins. | |
return apply_filters( 'wc_pagarme_transaction_data', $data , $order ); | |
} | |
/** | |
* Get customer data from checkout pay page. | |
* | |
* @return array | |
*/ | |
public function get_customer_data_from_checkout_pay_page() { | |
global $wp; | |
$order = wc_get_order( (int) $wp->query_vars['order-pay'] ); | |
$data = $this->generate_transaction_data( $order, array() ); | |
$customer = array(); | |
if ( empty( $data['customer'] ) ) { | |
return $customer; | |
} | |
$_customer = $data['customer']; | |
$customer['customerName'] = $_customer['name']; | |
$customer['customerEmail'] = $_customer['email']; | |
if ( isset( $_customer['document_number'] ) ) { | |
$customer['customerDocumentNumber'] = $_customer['document_number']; | |
} | |
if ( isset( $_customer['address'] ) ) { | |
$customer['customerAddressStreet'] = $_customer['address']['street']; | |
$customer['customerAddressComplementary'] = $_customer['address']['complementary']; | |
$customer['customerAddressZipcode'] = $_customer['address']['zipcode']; | |
if ( isset( $_customer['address']['street_number'] ) ) { | |
$customer['customerAddressStreetNumber'] = $_customer['address']['street_number']; | |
} | |
if ( isset( $_customer['address']['neighborhood'] ) ) { | |
$customer['customerAddressNeighborhood'] = $_customer['address']['neighborhood']; | |
} | |
} | |
if ( isset( $_customer['phone'] ) ) { | |
$customer['customerPhoneDdd'] = $_customer['phone']['ddd']; | |
$customer['customerPhoneNumber'] = $_customer['phone']['number']; | |
} | |
return $customer; | |
} | |
/** | |
* Get transaction data. | |
* | |
* @param WC_Order $order Order data. | |
* @param string $token Checkout token. | |
* | |
* @return array Response data. | |
*/ | |
public function get_transaction_data( $order, $token ) { | |
if ( 'yes' === $this->gateway->debug ) { | |
$this->gateway->log->add( $this->gateway->id, 'Getting transaction data for order ' . $order->get_order_number() . '...' ); | |
} | |
$response = $this->do_request( 'transactions/' . $token, 'GET', array( 'api_key' => $this->gateway->api_key ) ); | |
if ( is_wp_error( $response ) ) { | |
if ( 'yes' === $this->gateway->debug ) { | |
$this->gateway->log->add( $this->gateway->id, 'WP_Error in getting transaction data: ' . $response->get_error_message() ); | |
} | |
return array(); | |
} else { | |
$data = json_decode( $response['body'], true ); | |
if ( isset( $data['errors'] ) ) { | |
if ( 'yes' === $this->gateway->debug ) { | |
$this->gateway->log->add( $this->gateway->id, 'Failed to get transaction data: ' . print_r( $response, true ) ); | |
} | |
return $data; | |
} | |
if ( 'yes' === $this->gateway->debug ) { | |
$this->gateway->log->add( $this->gateway->id, 'Transaction data obtained successfully!' ); | |
} | |
return $data; | |
} | |
} | |
/** | |
* Generate checkout data. | |
* | |
* @param WC_Order $order Order data. | |
* @param string $token Checkout token. | |
* | |
* @return array Checkout data. | |
*/ | |
public function generate_checkout_data( $order, $token ) { | |
$transaction = $this->get_transaction_data( $order, $token ); | |
$installments = $this->get_installments( $order->get_total() ); | |
// Valid transaction. | |
if ( ! isset( $transaction['amount'] ) ) { | |
return array( 'error' => __( 'Invalid transaction data.', 'woocommerce-pagarme' ) ); | |
} | |
// Test if using more installments that allowed. | |
if ( $this->gateway->max_installment < $transaction['installments'] || empty( $installments[ $transaction['installments'] ] ) ) { | |
if ( 'yes' === $this->gateway->debug ) { | |
$this->gateway->log->add( $this->gateway->id, 'Payment made with more installments than allowed for order ' . $order->get_order_number() ); | |
} | |
return array( 'error' => __( 'Payment made with more installments than allowed.', 'woocommerce-pagarme' ) ); | |
} | |
$installment = $installments[ $transaction['installments'] ]; | |
// Test smallest installment amount. | |
if ( 1 !== intval( $transaction['installments'] ) && $this->get_smallest_installment() > $installment['installment_amount'] ) { | |
if ( 'yes' === $this->gateway->debug ) { | |
$this->gateway->log->add( $this->gateway->id, 'Payment divided into a lower amount than permitted for order ' . $order->get_order_number() ); | |
} | |
return array( 'error' => __( 'Payment divided into a lower amount than permitted.', 'woocommerce-pagarme' ) ); | |
} | |
// Check the transaction amount. | |
if ( intval( $transaction['amount'] ) !== intval( $installment['amount'] ) ) { | |
if ( 'yes' === $this->gateway->debug ) { | |
$this->gateway->log->add( $this->gateway->id, 'Wrong payment amount total for order ' . $order->get_order_number() ); | |
} | |
return array( 'error' => __( 'Wrong payment amount total.', 'woocommerce-pagarme' ) ); | |
} | |
$data = array( | |
'api_key' => $this->gateway->api_key, | |
'amount' => $transaction['amount'], | |
'metadata' => array( | |
'order_number' => $order->get_order_number(), | |
), | |
); | |
return apply_filters( 'wc_pagarme_checkout_data', $data ); | |
} | |
/** | |
* Do the transaction. | |
* | |
* @param WC_Order $order Order data. | |
* @param array $args Transaction args. | |
* @param string $token Checkout token. | |
* | |
* @return array Response data. | |
*/ | |
public function do_transaction( $order, $args, $token = '' ) { | |
if ( 'yes' === $this->gateway->debug ) { | |
$this->gateway->log->add( $this->gateway->id, 'Doing a transaction for order ' . $order->get_order_number() . '...' ); | |
} | |
$endpoint = 'transactions'; | |
if ( ! empty( $token ) ) { | |
$endpoint .= '/' . $token . '/capture'; | |
} | |
$response = $this->do_request( $endpoint, 'POST', $args ); | |
if ( is_wp_error( $response ) ) { | |
if ( 'yes' === $this->gateway->debug ) { | |
$this->gateway->log->add( $this->gateway->id, 'WP_Error in doing the transaction: ' . $response->get_error_message() ); | |
} | |
return array(); | |
} else { | |
$data = json_decode( $response['body'], true ); | |
if ( isset( $data['errors'] ) ) { | |
if ( 'yes' === $this->gateway->debug ) { | |
$this->gateway->log->add( $this->gateway->id, 'Failed to make the transaction: ' . print_r( $response, true ) ); | |
} | |
return $data; | |
} | |
if ( 'yes' === $this->gateway->debug ) { | |
$this->gateway->log->add( $this->gateway->id, 'Transaction completed successfully! The transaction response is: ' . print_r( $data, true ) ); | |
} | |
return $data; | |
} | |
} | |
/** | |
* Refund the order. | |
* | |
* @param WC_Order $order Order data. | |
* @param float $amount Amount to refund. | |
* | |
* @return bool Successfully refunded. | |
*/ | |
public function do_refund( $order_id, $amount ) { | |
$order = wc_get_order( $order_id ); | |
$transaction_id = get_post_meta( $order_id, '_wc_pagarme_transaction_id', true ); | |
$endpoint = 'transactions/' . $transaction_id . '/refund'; | |
$data = array ( | |
'api_key' => $this->gateway->api_key, | |
); | |
if ( 'yes' === $this->gateway->debug ) { | |
$this->gateway->log->add( $this->gateway->id, 'Starting refunding for order. ID: ' . $order->get_order_number() . '...' ); | |
} | |
if ( ! in_array( $order->get_status(), array( 'processing', 'completed' ), true ) ) { | |
if ( 'yes' === $this->gateway->debug ) { | |
$this->gateway->log->add( $this->gateway->id, 'Can\'t refund unpaid order. ID: ' . $order->get_order_number() ); | |
} | |
return false; | |
} | |
if ( $order->get_total() < $amount ) { | |
if ( 'yes' === $this->gateway->debug ) { | |
$this->gateway->log->add( $this->gateway->id, 'Can\'t refund more than the paid amount. ID: ' . $order->get_order_number() ); | |
} | |
return false; | |
} | |
if ( $amount <= 0 ) { | |
if ( 'yes' === $this->gateway->debug ) { | |
$this->gateway->log->add( $this->gateway->id, 'Can\'t refund when amount is zero or negative. ID: ' . $order->get_order_number() ); | |
} | |
return false; | |
} | |
$is_partially_refund = $amount < $order->get_total(); | |
if ( $is_partially_refund ){ | |
if ( 'yes' === $this->gateway->debug ) { | |
$this->gateway->log->add( $this->gateway->id, 'Refunding order partially. ID: ' . $order->get_order_number() . '...' ); | |
$this->gateway->log->add( $this->gateway->id, 'Order total: ' . $order->get_total() . ', Refund total: ' . $amount ); | |
} | |
$data['amount'] = $amount * 100; | |
} | |
$response = $this->do_request( $endpoint, 'POST', $data ); | |
if ( is_wp_error( $response ) ) { | |
if ( 'yes' === $this->gateway->debug ) { | |
$this->gateway->log->add( $this->gateway->id, 'Error doing refund: ' . $response->get_error_message() ); | |
} | |
return false; | |
} | |
$response_data = json_decode( $response['body'], true ); | |
if ( isset( $response_data['errors'] ) ) { | |
if ( 'yes' === $this->gateway->debug ) { | |
$this->gateway->log->add( $this->gateway->id, 'Failed to make the refund: ' . print_r( $response, true ) ); | |
} | |
return false; | |
} | |
return true; | |
} | |
/** | |
* Do the transaction. | |
* | |
* @param WC_Order $order Order data. | |
* @param string $token Checkout token. | |
* | |
* @return array Response data. | |
*/ | |
public function cancel_transaction( $order, $token ) { | |
if ( 'yes' === $this->gateway->debug ) { | |
$this->gateway->log->add( $this->gateway->id, 'Cancelling transaction for order ' . $order->get_order_number() . '...' ); | |
} | |
$endpoint = 'transactions'; | |
if ( ! empty( $token ) ) { | |
$endpoint .= '/' . $token . '/refund'; | |
} | |
$response = $this->do_request( $endpoint, 'POST', array( 'api_key' => $this->gateway->api_key ) ); | |
if ( is_wp_error( $response ) ) { | |
if ( 'yes' === $this->gateway->debug ) { | |
$this->gateway->log->add( $this->gateway->id, 'WP_Error in doing the transaction cancellation: ' . $response->get_error_message() ); | |
} | |
return array(); | |
} else { | |
$data = json_decode( $response['body'], true ); | |
if ( isset( $data['errors'] ) ) { | |
if ( 'yes' === $this->gateway->debug ) { | |
$this->gateway->log->add( $this->gateway->id, 'Failed to cancel the transaction: ' . print_r( $response, true ) ); | |
} | |
return $data; | |
} | |
if ( 'yes' === $this->gateway->debug ) { | |
$this->gateway->log->add( $this->gateway->id, 'Transaction canceled successfully! The response is: ' . print_r( $data, true ) ); | |
} | |
return $data; | |
} | |
} | |
/** | |
* Get card brand name. | |
* | |
* @param string $brand Card brand. | |
* @return string | |
*/ | |
protected function get_card_brand_name( $brand ) { | |
$names = array( | |
'visa' => __( 'Visa', 'woocommerce-pagarme' ), | |
'mastercard' => __( 'MasterCard', 'woocommerce-pagarme' ), | |
'amex' => __( 'American Express', 'woocommerce-pagarme' ), | |
'aura' => __( 'Aura', 'woocommerce-pagarme' ), | |
'jcb' => __( 'JCB', 'woocommerce-pagarme' ), | |
'diners' => __( 'Diners', 'woocommerce-pagarme' ), | |
'elo' => __( 'Elo', 'woocommerce-pagarme' ), | |
'hipercard' => __( 'Hipercard', 'woocommerce-pagarme' ), | |
'discover' => __( 'Discover', 'woocommerce-pagarme' ), | |
); | |
return isset( $names[ $brand ] ) ? $names[ $brand ] : $brand; | |
} | |
/** | |
* Save order meta fields. | |
* Save fields as meta data to display on order's admin screen. | |
* | |
* @param int $id Order ID. | |
* @param array $data Order data. | |
*/ | |
protected function save_order_meta_fields( $id, $data ) { | |
// Transaction data. | |
$payment_data = array_map( | |
'sanitize_text_field', | |
array( | |
'payment_method' => $data['payment_method'], | |
'installments' => $data['installments'], | |
'card_brand' => $this->get_card_brand_name( $data['card_brand'] ), | |
'antifraud_score' => $data['antifraud_score'], | |
'boleto_url' => $data['boleto_url'], | |
) | |
); | |
// Meta data. | |
$meta_data = array( | |
__( 'Banking Ticket URL', 'woocommerce-pagarme' ) => sanitize_text_field( $data['boleto_url'] ), | |
__( 'Credit Card', 'woocommerce-pagarme' ) => $this->get_card_brand_name( sanitize_text_field( $data['card_brand'] ) ), | |
__( 'Installments', 'woocommerce-pagarme' ) => sanitize_text_field( $data['installments'] ), | |
__( 'Total paid', 'woocommerce-pagarme' ) => number_format( intval( $data['amount'] ) / 100, wc_get_price_decimals(), wc_get_price_decimal_separator(), wc_get_price_thousand_separator() ), | |
__( 'Anti Fraud Score', 'woocommerce-pagarme' ) => sanitize_text_field( $data['antifraud_score'] ), | |
'_wc_pagarme_transaction_data' => $payment_data, | |
'_wc_pagarme_transaction_id' => intval( $data['id'] ), | |
'_transaction_id' => intval( $data['id'] ), | |
); | |
$order = wc_get_order( $id ); | |
// WooCommerce 3.0 or later. | |
if ( ! method_exists( $order, 'update_meta_data' ) ) { | |
foreach ( $meta_data as $key => $value ) { | |
update_post_meta( $id, $key, $value ); | |
} | |
} else { | |
foreach ( $meta_data as $key => $value ) { | |
$order->update_meta_data( $key, $value ); | |
} | |
$order->save(); | |
} | |
} | |
/** | |
* Process regular payment. | |
* | |
* @param int $order_id Order ID. | |
* | |
* @return array Redirect data. | |
*/ | |
public function process_regular_payment( $order_id ) { | |
$order = wc_get_order( $order_id ); | |
$is_checkout_pagarme = isset( $this->gateway->checkout ) && 'yes' === $this->gateway->checkout; | |
$register_refused_order = isset( $this->gateway->register_refused_order ) && 'yes' === $this->gateway->register_refused_order; | |
if ( $is_checkout_pagarme && ! $register_refused_order ) { | |
if ( ! empty( $_POST['pagarme_checkout_token'] ) ) { | |
$token = sanitize_text_field( wp_unslash( $_POST['pagarme_checkout_token'] ) ); | |
$data = $this->generate_checkout_data( $order, $token ); | |
// Cancel the payment is irregular. | |
if ( isset( $data['error'] ) ) { | |
$this->cancel_transaction( $order, $token ); | |
$order->update_status( 'failed', $data['error'] ); | |
return array( | |
'result' => 'success', | |
'redirect' => $this->gateway->get_return_url( $order ), | |
); | |
} | |
$transaction = $this->do_transaction( $order, $data, $token ); | |
} else { | |
$transaction = array( 'errors' => array( array( 'message' => __( 'Missing credit card data, please review your data and try again or contact us for assistance.', 'woocommerce-pagarme' ) ) ) ); | |
} | |
} else { | |
$data = $this->generate_transaction_data( $order, $_POST ); | |
$transaction = $this->do_transaction( $order, $data ); | |
} | |
if ( isset( $transaction['errors'] ) ) { | |
foreach ( $transaction['errors'] as $error ) { | |
wc_add_notice( $error['message'], 'error' ); | |
} | |
return array( | |
'result' => 'fail', | |
); | |
} else { | |
$this->save_order_meta_fields( $order_id, $transaction ); | |
$this->process_order_status( $order, $transaction['status'] ); | |
// Empty the cart. | |
WC()->cart->empty_cart(); | |
// Redirect to thanks page. | |
return array( | |
'result' => 'success', | |
'redirect' => $this->gateway->get_return_url( $order ), | |
); | |
} | |
} | |
/** | |
* Check if Pagar.me response is validity. | |
* | |
* @param array $ipn_response IPN response data. | |
* | |
* @return bool | |
*/ | |
public function check_fingerprint( $ipn_response ) { | |
$signature = $_SERVER['HTTP_X_HUB_SIGNATURE']; | |
$parts = explode('=', $signature, 2); | |
if (count($parts) != 2) { | |
return false; | |
} | |
$api_key = $this->gateway->api_key; | |
$hash = hash_hmac($parts[0], $ipn_response, $api_key); | |
$log = []; | |
$log['parts'] = $parts; | |
$log['hash'] = $hash; | |
$log['ipn_response'] = $ipn_response; | |
return $hash === $parts[1]; | |
} | |
/** | |
* Send email notification. | |
* | |
* @param string $subject Email subject. | |
* @param string $title Email title. | |
* @param string $message Email message. | |
*/ | |
protected function send_email( $subject, $title, $message ) { | |
$mailer = WC()->mailer(); | |
$mailer->send( get_option( 'admin_email' ), $subject, $mailer->wrap_message( $title, $message ) ); | |
} | |
/** | |
* IPN handler. | |
*/ | |
public function ipn_handler() { | |
@ob_clean(); | |
$ipn_response = file_get_contents('php://input'); | |
if ( $ipn_response && $this->check_fingerprint( $ipn_response ) ) { | |
header( 'HTTP/1.1 200 OK' ); | |
parse_str( $ipn_response, $parsed_ipn_response ); | |
$this->process_successful_ipn( $parsed_ipn_response ); | |
// Deprecated action since 2.0.0. | |
do_action( 'wc_pagarme_valid_ipn_request', $ipn_response ); | |
exit; | |
} else { | |
wp_die( esc_html__( 'Pagar.me Request Failure', 'woocommerce-pagarme' ), '', array( 'response' => 401 ) ); | |
} | |
} | |
/** | |
* Process successeful IPN requests. | |
* | |
* @param array $posted Posted data. | |
*/ | |
public function process_successful_ipn( $posted ) { | |
global $wpdb; | |
$posted = wp_unslash( $posted ); | |
$order_id = absint( $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_wc_pagarme_transaction_id' AND meta_value = %d", $posted['id'] ) ) ); | |
$order = wc_get_order( $order_id ); | |
$status = sanitize_text_field( $posted['current_status'] ); | |
if ( $order && $order->id === $order_id ) { | |
$this->process_order_status( $order, $status ); | |
} | |
// Async transactions will only send the boleto_url on IPN. | |
if ( ! empty( $posted['transaction']['boleto_url'] ) && 'pagarme-banking-ticket' === $order->payment_method ) { | |
$post_data = get_post_meta( $order->id, '_wc_pagarme_transaction_data', true ); | |
$post_data['boleto_url'] = sanitize_text_field( $posted['transaction']['boleto_url'] ); | |
update_post_meta( $order->id, '_wc_pagarme_transaction_data', $post_data ); | |
} | |
} | |
/** | |
* Process the order status. | |
* | |
* @param WC_Order $order Order data. | |
* @param string $status Transaction status. | |
*/ | |
public function process_order_status( $order, $status ) { | |
if ( 'yes' === $this->gateway->debug ) { | |
$this->gateway->log->add( $this->gateway->id, 'Payment status for order ' . $order->get_order_number() . ' is now: ' . $status ); | |
} | |
switch ( $status ) { | |
case 'authorized' : | |
if ( ! in_array( $order->get_status(), array( 'processing', 'completed' ), true ) ) { | |
$order->update_status( 'on-hold', __( 'Pagar.me: The transaction was authorized.', 'woocommerce-pagarme' ) ); | |
} | |
break; | |
case 'pending_review': | |
$transaction_id = get_post_meta( $order->id, '_wc_pagarme_transaction_id', true ); | |
$transaction_url = '<a href="https://dashboard.pagar.me/#/transactions/' . intval( $transaction_id ) . '">https://dashboard.pagar.me/#/transactions/' . intval( $transaction_id ) . '</a>'; | |
/* translators: %s transaction details url */ | |
$order->update_status( 'on-hold', __( 'Pagar.me: You should manually analyze this transaction to continue payment flow, access %s to do it!', 'woocommerce-pagarme' ), $transaction_url ); | |
break; | |
case 'processing' : | |
$order->update_status( 'on-hold', __( 'Pagar.me: The transaction is being processed.', 'woocommerce-pagarme' ) ); | |
break; | |
case 'paid' : | |
if ( ! in_array( $order->get_status(), array( 'processing', 'completed' ), true ) ) { | |
$order->add_order_note( __( 'Pagar.me: Transaction paid.', 'woocommerce-pagarme' ) ); | |
} | |
// Changing the order for processing and reduces the stock. | |
$order->payment_complete(); | |
break; | |
case 'waiting_payment' : | |
$order->update_status( 'on-hold', __( 'Pagar.me: The banking ticket was issued but not paid yet.', 'woocommerce-pagarme' ) ); | |
break; | |
case 'refused' : | |
$order->update_status( 'failed', __( 'Pagar.me: The transaction was rejected by the card company or by fraud.', 'woocommerce-pagarme' ) ); | |
$transaction_id = get_post_meta( $order->id, '_wc_pagarme_transaction_id', true ); | |
$transaction_url = '<a href="https://dashboard.pagar.me/#/transactions/' . intval( $transaction_id ) . '">https://dashboard.pagar.me/#/transactions/' . intval( $transaction_id ) . '</a>'; | |
$this->send_email( | |
sprintf( esc_html__( 'The transaction for order %s was rejected by the card company or by fraud', 'woocommerce-pagarme' ), $order->get_order_number() ), | |
esc_html__( 'Transaction failed', 'woocommerce-pagarme' ), | |
sprintf( esc_html__( 'Order %1$s has been marked as failed, because the transaction was rejected by the card company or by fraud, for more details, see %2$s.', 'woocommerce-pagarme' ), $order->get_order_number(), $transaction_url ) | |
); | |
break; | |
case 'refunded' : | |
$order->update_status( 'refunded', __( 'Pagar.me: The transaction was refunded/canceled.', 'woocommerce-pagarme' ) ); | |
$transaction_id = get_post_meta( $order->id, '_wc_pagarme_transaction_id', true ); | |
$transaction_url = '<a href="https://dashboard.pagar.me/#/transactions/' . intval( $transaction_id ) . '">https://dashboard.pagar.me/#/transactions/' . intval( $transaction_id ) . '</a>'; | |
$this->send_email( | |
sprintf( esc_html__( 'The transaction for order %s refunded', 'woocommerce-pagarme' ), $order->get_order_number() ), | |
esc_html__( 'Transaction refunded', 'woocommerce-pagarme' ), | |
sprintf( esc_html__( 'Order %1$s has been marked as refunded by Pagar.me, for more details, see %2$s.', 'woocommerce-pagarme' ), $order->get_order_number(), $transaction_url ) | |
); | |
break; | |
case 'analyzing' : | |
$order->update_status( 'on-hold', __( 'Pagar.me: Transaction is waiting for antifraud analysis.', 'woocommerce-pagarme' ) ); | |
break; | |
default : | |
break; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment