2020-06-01 14:03:18 +02:00
< ? php
/**
2020-09-06 11:38:10 +02:00
* Invoice Ninja ( https :// invoiceninja . com ) .
2020-06-01 14:03:18 +02:00
*
* @ link https :// github . com / invoiceninja / invoiceninja source repository
*
2021-01-03 22:54:54 +01:00
* @ copyright Copyright ( c ) 2021. Invoice Ninja LLC ( https :// invoiceninja . com )
2020-06-01 14:03:18 +02:00
*
2021-06-16 08:58:16 +02:00
* @ license https :// www . elastic . co / licensing / elastic - license
2020-06-01 14:03:18 +02:00
*/
namespace App\PaymentDrivers\Stripe ;
2020-11-01 16:52:37 +01:00
use App\Exceptions\PaymentFailed ;
2020-11-01 16:37:41 +01:00
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest ;
2020-06-01 16:19:03 +02:00
use App\Jobs\Util\SystemLogger ;
2020-06-01 14:14:41 +02:00
use App\Models\GatewayType ;
2020-06-09 13:07:18 +02:00
use App\Models\Payment ;
2020-06-01 16:19:03 +02:00
use App\Models\PaymentType ;
use App\Models\SystemLog ;
2020-06-01 14:03:18 +02:00
use App\PaymentDrivers\StripePaymentDriver ;
2020-12-21 11:46:10 +01:00
use Stripe\PaymentIntent ;
use Stripe\PaymentMethod ;
2020-06-01 14:03:18 +02:00
class CreditCard
{
public $stripe ;
public function __construct ( StripePaymentDriver $stripe )
{
$this -> stripe = $stripe ;
}
public function authorizeView ( array $data )
{
$intent [ 'intent' ] = $this -> stripe -> getSetupIntent ();
2020-10-20 16:08:21 +02:00
return render ( 'gateways.stripe.credit_card.authorize' , array_merge ( $data , $intent ));
2020-06-01 14:03:18 +02:00
}
2020-06-01 14:14:41 +02:00
public function authorizeResponse ( $request )
{
2020-10-28 16:31:47 +01:00
$this -> stripe -> init ();
2020-06-01 14:14:41 +02:00
2020-10-28 16:31:47 +01:00
$stripe_response = json_decode ( $request -> input ( 'gateway_response' ));
2020-06-01 14:14:41 +02:00
$customer = $this -> stripe -> findOrCreateCustomer ();
2020-11-01 16:37:41 +01:00
2020-10-28 16:31:47 +01:00
$this -> stripe -> attach ( $stripe_response -> payment_method , $customer );
2020-06-01 14:14:41 +02:00
2020-10-28 16:31:47 +01:00
$stripe_method = $this -> stripe -> getStripePaymentMethod ( $stripe_response -> payment_method );
2020-06-01 14:14:41 +02:00
2020-10-28 16:48:24 +01:00
$this -> storePaymentMethod ( $stripe_method , $request -> payment_method_id , $customer );
2020-06-01 14:14:41 +02:00
return redirect () -> route ( 'client.payment_methods.index' );
}
2020-06-01 14:29:41 +02:00
public function paymentView ( array $data )
{
2022-02-02 09:51:29 +01:00
$description = $this -> stripe -> decodeUnicodeString ( ctrans ( 'texts.invoices' ) . ': ' . collect ( $data [ 'invoices' ]) -> pluck ( 'invoice_number' )) . " for client { $this -> stripe -> client -> present () -> name () } " ;
2020-06-01 14:29:41 +02:00
$payment_intent_data = [
2021-06-30 05:56:11 +02:00
'amount' => $this -> stripe -> convertToStripeAmount ( $data [ 'total' ][ 'amount_with_fee' ], $this -> stripe -> client -> currency () -> precision , $this -> stripe -> client -> currency ()),
2020-06-01 14:29:41 +02:00
'currency' => $this -> stripe -> client -> getCurrencyCode (),
'customer' => $this -> stripe -> findOrCreateCustomer (),
2022-02-02 09:51:29 +01:00
'description' => $description ,
2022-01-24 04:24:47 +01:00
'metadata' => [
'payment_hash' => $this -> stripe -> payment_hash -> hash ,
'gateway_type_id' => GatewayType :: CREDIT_CARD ,
],
'setup_future_usage' => 'off_session' ,
2020-06-01 14:29:41 +02:00
];
$data [ 'intent' ] = $this -> stripe -> createPaymentIntent ( $payment_intent_data );
$data [ 'gateway' ] = $this -> stripe ;
2020-10-20 16:08:21 +02:00
return render ( 'gateways.stripe.credit_card.pay' , $data );
2020-06-01 14:29:41 +02:00
}
2021-09-02 08:17:46 +02:00
private function decodeUnicodeString ( $string )
{
2021-09-07 23:05:53 +02:00
return html_entity_decode ( $string , ENT_QUOTES , 'UTF-8' );
// return iconv("UTF-8", "ISO-8859-1//TRANSLIT", $this->decode_encoded_utf8($string));
2021-09-02 08:17:46 +02:00
}
private function decode_encoded_utf8 ( $string ){
return preg_replace_callback ( '#\\\\u([0-9a-f]{4})#ism' , function ( $matches ) { return mb_convert_encoding ( pack ( " H* " , $matches [ 1 ]), " UTF-8 " , " UCS-2BE " ); }, $string );
}
2020-11-01 16:37:41 +01:00
public function paymentResponse ( PaymentResponseRequest $request )
2020-06-01 14:29:41 +02:00
{
2020-11-01 16:37:41 +01:00
$this -> stripe -> init ();
2020-08-30 14:00:19 +02:00
2020-06-01 16:19:03 +02:00
$state = [
2020-11-01 16:37:41 +01:00
'server_response' => json_decode ( $request -> gateway_response ),
'payment_hash' => $request -> payment_hash ,
2020-06-01 16:19:03 +02:00
];
2020-11-01 16:37:41 +01:00
$state = array_merge ( $state , $request -> all ());
$state [ 'store_card' ] = boolval ( $state [ 'store_card' ]);
2020-06-01 16:19:03 +02:00
2021-02-03 16:49:29 +01:00
if ( $request -> has ( 'token' ) && ! is_null ( $request -> token )) {
$state [ 'store_card' ] = false ;
}
2021-05-12 00:14:29 +02:00
$state [ 'payment_intent' ] = PaymentIntent :: retrieve ( $state [ 'server_response' ] -> id , $this -> stripe -> stripe_connect_auth );
2020-11-01 16:37:41 +01:00
$state [ 'customer' ] = $state [ 'payment_intent' ] -> customer ;
2020-06-01 16:19:03 +02:00
2020-11-01 16:37:41 +01:00
$this -> stripe -> payment_hash -> data = array_merge (( array ) $this -> stripe -> payment_hash -> data , $state );
$this -> stripe -> payment_hash -> save ();
2020-06-01 16:19:03 +02:00
2020-11-01 16:37:41 +01:00
$server_response = $this -> stripe -> payment_hash -> data -> server_response ;
2020-08-30 14:00:19 +02:00
2020-11-01 16:37:41 +01:00
if ( $server_response -> status == 'succeeded' ) {
2020-08-30 14:00:19 +02:00
2021-01-11 23:14:52 +01:00
$this -> stripe -> logSuccessfulGatewayResponse ([ 'response' => json_decode ( $request -> gateway_response ), 'data' => $this -> stripe -> payment_hash ], SystemLog :: TYPE_STRIPE );
2021-01-11 23:06:56 +01:00
2020-11-01 16:37:41 +01:00
return $this -> processSuccessfulPayment ();
2020-06-01 16:19:03 +02:00
}
return $this -> processUnsuccessfulPayment ( $server_response );
}
2021-08-16 00:54:11 +02:00
public function processSuccessfulPayment ()
2020-06-01 16:19:03 +02:00
{
2020-11-01 16:37:41 +01:00
$stripe_method = $this -> stripe -> getStripePaymentMethod ( $this -> stripe -> payment_hash -> data -> server_response -> payment_method );
2020-12-21 11:46:10 +01:00
2020-11-16 13:37:13 +01:00
$data = [
'payment_method' => $this -> stripe -> payment_hash -> data -> server_response -> payment_method ,
2021-12-03 03:43:13 +01:00
'payment_type' => PaymentType :: parseCardType ( strtolower ( $stripe_method -> card -> brand )) ? : PaymentType :: CREDIT_CARD_OTHER ,
2021-06-30 05:56:11 +02:00
'amount' => $this -> stripe -> convertFromStripeAmount ( $this -> stripe -> payment_hash -> data -> server_response -> amount , $this -> stripe -> client -> currency () -> precision , $this -> stripe -> client -> currency ()),
2020-12-01 13:46:09 +01:00
'transaction_reference' => optional ( $this -> stripe -> payment_hash -> data -> payment_intent -> charges -> data [ 0 ]) -> id ,
2021-01-27 11:38:28 +01:00
'gateway_type_id' => GatewayType :: CREDIT_CARD ,
2020-11-16 13:37:13 +01:00
];
$this -> stripe -> payment_hash -> data = array_merge (( array ) $this -> stripe -> payment_hash -> data , [ 'amount' => $data [ 'amount' ]]);
$this -> stripe -> payment_hash -> save ();
2020-11-01 16:37:41 +01:00
if ( $this -> stripe -> payment_hash -> data -> store_card ) {
2020-11-16 14:10:45 +01:00
$customer = new \stdClass ;
$customer -> id = $this -> stripe -> payment_hash -> data -> customer ;
2020-06-01 16:19:03 +02:00
2020-11-01 16:37:41 +01:00
$this -> stripe -> attach ( $this -> stripe -> payment_hash -> data -> server_response -> payment_method , $customer );
2020-12-21 11:46:10 +01:00
2020-11-16 14:10:45 +01:00
$stripe_method = $this -> stripe -> getStripePaymentMethod ( $this -> stripe -> payment_hash -> data -> server_response -> payment_method );
2020-12-21 11:46:10 +01:00
2020-11-01 16:37:41 +01:00
$this -> storePaymentMethod ( $stripe_method , $this -> stripe -> payment_hash -> data -> payment_method_id , $customer );
2020-06-01 16:19:03 +02:00
}
2020-12-21 11:46:10 +01:00
$payment = $this -> stripe -> createPayment ( $data , Payment :: STATUS_COMPLETED );
2020-06-01 16:19:03 +02:00
2020-11-01 16:37:41 +01:00
SystemLogger :: dispatch (
[ 'response' => $this -> stripe -> payment_hash -> data -> server_response , 'data' => $data ],
SystemLog :: CATEGORY_GATEWAY_RESPONSE ,
SystemLog :: EVENT_GATEWAY_SUCCESS ,
SystemLog :: TYPE_STRIPE ,
2021-05-19 03:12:23 +02:00
$this -> stripe -> client ,
$this -> stripe -> client -> company ,
2020-11-01 16:37:41 +01:00
);
2020-07-01 18:28:57 +02:00
2020-06-01 16:19:03 +02:00
return redirect () -> route ( 'client.payments.show' , [ 'payment' => $this -> stripe -> encodePrimaryKey ( $payment -> id )]);
}
2021-08-16 00:54:11 +02:00
public function processUnsuccessfulPayment ( $server_response )
2020-06-01 16:19:03 +02:00
{
2021-10-17 12:40:40 +02:00
$this -> stripe -> sendFailureMail ( $server_response -> cancellation_reason );
2020-11-01 16:52:37 +01:00
2020-06-01 16:19:03 +02:00
$message = [
'server_response' => $server_response ,
2020-11-01 16:52:37 +01:00
'data' => $this -> stripe -> payment_hash -> data ,
2020-06-01 16:19:03 +02:00
];
2020-11-01 16:52:37 +01:00
SystemLogger :: dispatch (
$message ,
SystemLog :: CATEGORY_GATEWAY_RESPONSE ,
SystemLog :: EVENT_GATEWAY_FAILURE ,
SystemLog :: TYPE_STRIPE ,
2021-05-19 03:12:23 +02:00
$this -> stripe -> client ,
$this -> stripe -> client -> company ,
2020-11-01 16:52:37 +01:00
);
2020-06-01 16:19:03 +02:00
2020-11-01 16:52:37 +01:00
throw new PaymentFailed ( 'Failed to process the payment.' , 500 );
2020-06-01 16:19:03 +02:00
}
2020-10-28 16:31:47 +01:00
2020-12-21 11:46:10 +01:00
private function storePaymentMethod ( PaymentMethod $method , $payment_method_id , $customer )
2020-10-28 16:31:47 +01:00
{
try {
$payment_meta = new \stdClass ;
$payment_meta -> exp_month = ( string ) $method -> card -> exp_month ;
$payment_meta -> exp_year = ( string ) $method -> card -> exp_year ;
$payment_meta -> brand = ( string ) $method -> card -> brand ;
$payment_meta -> last4 = ( string ) $method -> card -> last4 ;
$payment_meta -> type = GatewayType :: CREDIT_CARD ;
$data = [
'payment_meta' => $payment_meta ,
'token' => $method -> id ,
'payment_method_id' => $payment_method_id ,
];
2020-10-28 16:48:24 +01:00
$this -> stripe -> storeGatewayToken ( $data , [ 'gateway_customer_reference' => $customer -> id ]);
2020-10-28 16:31:47 +01:00
} catch ( \Exception $e ) {
return $this -> stripe -> processInternallyFailedPayment ( $this -> stripe , $e );
}
}
2020-06-01 14:14:41 +02:00
}