Last active
February 8, 2022 09:48
-
-
Save Prometee/8c53130648c6381e75d27812b751d43c to your computer and use it in GitHub Desktop.
[Sylius] Payum Stripe Checkout Session with Stripe Connect direct charge
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 | |
declare(strict_types=1); | |
namespace App\PayumStripe\Action\StripeCheckoutSession; | |
use App\PayumStripe\Provider\OnboardedUserInfoProviderInterface; | |
use ArrayObject; | |
use FluxSE\PayumStripe\Action\StripeCheckoutSession\CaptureAction; | |
use FluxSE\PayumStripe\Request\Api\Resource\CreateSession; | |
use Payum\Core\Request\Generic; | |
use Stripe\ApiResource; | |
use Sylius\Component\Core\Model\PaymentInterface; | |
final class CaptureThirdPartyAction extends CaptureAction | |
{ | |
private OnboardedUserInfoProviderInterface $onboardedUserInfoProvider; | |
public function __construct(OnboardedUserInfoProviderInterface $onboardedUserInfoProvider) | |
{ | |
$this->onboardedUserInfoProvider = $onboardedUserInfoProvider; | |
} | |
protected function createApiResource(ArrayObject $model, Generic $request): ApiResource | |
{ | |
$token = $this->getRequestToken($request); | |
$model->offsetSet('success_url', $token->getAfterUrl()); | |
$model->offsetSet('cancel_url', $token->getAfterUrl()); | |
$options = []; | |
$modeDataKey = $this->detectModeData($model); | |
/** @var PaymentInterface $payment */ | |
$payment = $request->getFirstModel(); | |
$stripeAccount = $this->onboardedUserInfoProvider->getStripeAccountFromPayment($payment); | |
if ('payment_intent_data' === $modeDataKey && null !== $stripeAccount) { | |
$this->embedStripeConnectInfo($model, $payment); | |
$options['stripe_account'] = $stripeAccount; | |
} | |
$createRequest = new CreateSession($model->getArrayCopy(), $options); | |
$this->gateway->execute($createRequest); | |
return $createRequest->getApiResource(); | |
} | |
private function embedStripeConnectInfo(ArrayObject $model, PaymentInterface $payment) | |
{ | |
$paymentIntentData = $model->offsetGet('payment_intent_data'); | |
if (null === $paymentIntentData) { | |
$paymentIntentData = []; | |
} | |
$metadata = []; | |
if ($model->offsetExists('metadata')) { | |
$metadata = $model->offsetGet('metadata'); | |
} | |
$stripeAccount = $this->onboardedUserInfoProvider->getStripeAccountFromPayment($payment); | |
$applicationFeeAmount = $this->onboardedUserInfoProvider->getApplicationFeeAmountFromPayment($payment); | |
$paymentIntentData['metadata']['stripe_account'] = $stripeAccount; | |
$paymentIntentData['application_fee_amount'] = $applicationFeeAmount; | |
$model->offsetSet('payment_intent_data', $paymentIntentData); | |
$metadata['stripe_account'] = $stripeAccount; | |
$model->offsetSet('metadata', $metadata); | |
} | |
} |
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 | |
declare(strict_types=1); | |
namespace App\PayumStripe\Provider; | |
use Sylius\Component\Core\Model\PaymentInterface; | |
interface OnboardedUserInfoProviderInterface | |
{ | |
public function getStripeAccountFromPayment(PaymentInterface $payment): ?string; | |
public function getApplicationFeeAmountFromPayment(PaymentInterface $payment): ?int; | |
} |
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
services: | |
App\PayumStripe\Provider\OnboardedUserInfoProvider: ~ | |
App\PayumStripe\Action\StripeCheckoutSession\CaptureThirdPartyAction: | |
public: true | |
arguments: | |
$onboardedUserInfoProvider: '@App\PayumStripe\Provider\OnboardedUserInfoProvider' | |
tags: | |
- name: payum.action | |
factory: stripe_checkout_session | |
alias: app.sylius_payum_stripe.capture_third_party | |
prepend: true | |
App\PayumStripe\Action\StripeCheckoutSession\SyncThirdPartyAction: | |
public: true | |
tags: | |
- name: payum.action | |
factory: stripe_checkout_session | |
alias: app.sylius_payum_stripe.sync_third_party | |
prepend: true |
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 | |
declare(strict_types=1); | |
namespace App\PayumStripe\Action\StripeCheckoutSession; | |
use FluxSE\PayumStripe\Action\SyncAction as BaseSyncAction; | |
use FluxSE\PayumStripe\Request\Api\Resource\RetrieveInterface; | |
use FluxSE\PayumStripe\Request\Api\Resource\RetrieveSession; | |
use Payum\Core\Bridge\Spl\ArrayObject; | |
use Stripe\Checkout\Session; | |
use Stripe\PaymentIntent; | |
final class SyncThirdPartyAction extends BaseSyncAction | |
{ | |
protected function syncSession(ArrayObject $model): void | |
{ | |
$objectName = (string) $model->offsetGet('object'); | |
if (Session::OBJECT_NAME !== $objectName) { | |
return; | |
} | |
$options = []; | |
$sessionModeObjectName = PaymentIntent::OBJECT_NAME; | |
if ($model->offsetExists($sessionModeObjectName)) { | |
$options = $this->getPaymentIntentOptions($sessionModeObjectName, $model); | |
} | |
$sessionRequest = new RetrieveSession( | |
(string) $model->offsetGet('id'), | |
$options | |
); | |
$this->gateway->execute($sessionRequest); | |
$session = $sessionRequest->getApiResource(); | |
$model->exchangeArray($session->toArray()); | |
} | |
protected function findSessionModeIdInSession(ArrayObject $model): ?RetrieveInterface | |
{ | |
foreach ($this->sessionModes as $sessionModeObjectName => $retrieveRequest) { | |
$sessionModeId = $model->offsetGet($sessionModeObjectName); | |
if (empty($sessionModeId)) { | |
continue; | |
} | |
return new $retrieveRequest( | |
(string) $sessionModeId, | |
// Added to allow filling the third party `stripe_account` | |
$this->getPaymentIntentOptions($sessionModeObjectName, $model) | |
); | |
} | |
return null; | |
} | |
protected function findSessionModeIdInModeObject(ArrayObject $model): ?RetrieveInterface | |
{ | |
$objectName = (string) $model->offsetGet('object'); | |
foreach ($this->sessionModes as $sessionModeObjectName => $retrieveRequest) { | |
if ($sessionModeObjectName !== $objectName) { | |
continue; | |
} | |
$sessionModeId = $model->offsetGet('id'); | |
return new $retrieveRequest( | |
(string) $sessionModeId, | |
// Added to allow filling the third party `stripe_account` | |
$this->getPaymentIntentOptions($sessionModeObjectName, $model) | |
); | |
} | |
return null; | |
} | |
private function getPaymentIntentOptions(string $sessionModeObjectName, ArrayObject $model): array | |
{ | |
$options = []; | |
$stripeAccount = $model['metadata']['stripe_account'] ?? null; | |
if (PaymentIntent::OBJECT_NAME === $sessionModeObjectName && null !== $stripeAccount) { | |
$options['stripe_account'] = $stripeAccount; | |
} | |
return $options; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment