From d343214a669c970bed26548c6a85ad2daa827cb1 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Thu, 8 Nov 2018 16:41:13 +0000 Subject: [PATCH 01/61] Add Product object typoe --- DependencyInjection/Configuration.php | 1 + Model/AbstractProductModel.php | 378 ++++++++++++++++++ .../model/AbstractProductModel.orm.xml | 28 ++ 3 files changed, 407 insertions(+) create mode 100644 Model/AbstractProductModel.php create mode 100644 Resources/config/doctrine/model/AbstractProductModel.orm.xml diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 445c87c..f11f9a2 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -47,6 +47,7 @@ public function getConfigTreeBuilder() ->scalarNode('customer')->cannotBeEmpty()->end() ->scalarNode('discount')->cannotBeEmpty()->end() ->scalarNode('invoice')->cannotBeEmpty()->end() + ->scalarNode('product')->cannotBeEmpty()->end() ->scalarNode('plan')->cannotBeEmpty()->end() ->scalarNode('refund')->cannotBeEmpty()->end() ->scalarNode('subscription')->cannotBeEmpty()->end() diff --git a/Model/AbstractProductModel.php b/Model/AbstractProductModel.php new file mode 100644 index 0000000..3393f9a --- /dev/null +++ b/Model/AbstractProductModel.php @@ -0,0 +1,378 @@ +object; + } + + /** + * @param string $object + */ + public function setObject($object) + { + $this->object = $object; + } + + /** + * @return bool + */ + public function isActive() + { + return $this->active; + } + + /** + * @param bool $active + */ + public function setActive($active) + { + $this->active = $active; + } + + /** + * @return array + */ + public function getAttributes() + { + return $this->attributes; + } + + /** + * @param array $attributes + */ + public function setAttributes($attributes) + { + $this->attributes = $attributes; + } + + /** + * @return int + */ + public function getCreated() + { + return $this->created; + } + + /** + * @param int $created + */ + public function setCreated($created) + { + $this->created = $created; + } + + /** + * @return array + */ + public function getDeactivateOn() + { + return $this->deactivateOn; + } + + /** + * @param array $deactivateOn + */ + public function setDeactivateOn($deactivateOn) + { + $this->deactivateOn = $deactivateOn; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } + + /** + * @param string $description + */ + public function setDescription($description) + { + $this->description = $description; + } + + /** + * @return array + */ + public function getImages() + { + return $this->images; + } + + /** + * @param array $images + */ + public function setImages($images) + { + $this->images = $images; + } + + /** + * @return bool + */ + public function isLivemode() + { + return $this->livemode; + } + + /** + * @param bool $livemode + */ + public function setLivemode($livemode) + { + $this->livemode = $livemode; + } + + /** + * @return array + */ + public function getMetadata() + { + return $this->metadata; + } + + /** + * @param array $metadata + */ + public function setMetadata($metadata) + { + $this->metadata = $metadata; + } + + /** + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * @param string $name + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * @return array + */ + public function getPackageDimensions() + { + return $this->packageDimensions; + } + + /** + * @param array $packageDimensions + */ + public function setPackageDimensions($packageDimensions) + { + $this->packageDimensions = $packageDimensions; + } + + /** + * @return bool + */ + public function isShippable() + { + return $this->shippable; + } + + /** + * @param bool $shippable + */ + public function setShippable($shippable) + { + $this->shippable = $shippable; + } + + /** + * @return string + */ + public function getStatementDescriptor() + { + return $this->statementDescriptor; + } + + /** + * @param string $statementDescriptor + */ + public function setStatementDescriptor($statementDescriptor) + { + $this->statementDescriptor = $statementDescriptor; + } + + /** + * @return string + */ + public function getType() + { + return $this->type; + } + + /** + * @param string $type + */ + public function setType($type) + { + $this->type = $type; + } + + /** + * @return int + */ + public function getUpdated() + { + return $this->updated; + } + + /** + * @param int $updated + */ + public function setUpdated($updated) + { + $this->updated = $updated; + } + + /** + * @return string + */ + public function getUrl() + { + return $this->url; + } + + /** + * @param string $url + */ + public function setUrl($url) + { + $this->url = $url; + } + + +} diff --git a/Resources/config/doctrine/model/AbstractProductModel.orm.xml b/Resources/config/doctrine/model/AbstractProductModel.orm.xml new file mode 100644 index 0000000..f01addb --- /dev/null +++ b/Resources/config/doctrine/model/AbstractProductModel.orm.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From fdd60379f35cd5622ff26907cb5d026770afcc11 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Mon, 12 Nov 2018 22:26:57 +0000 Subject: [PATCH 02/61] Implement Webhook Security --- Controller/WebhookController.php | 24 +++++++++++++++++++ DependencyInjection/Configuration.php | 3 +++ .../MiracodeStripeExtension.php | 5 ++++ .../MiracodeStripeExtensionTest.php | 13 ++++++++++ 4 files changed, 45 insertions(+) diff --git a/Controller/WebhookController.php b/Controller/WebhookController.php index 6ada74d..5461e2c 100644 --- a/Controller/WebhookController.php +++ b/Controller/WebhookController.php @@ -5,6 +5,8 @@ use Miracode\StripeBundle\Event\StripeEvent; use Miracode\StripeBundle\Stripe\StripeObjectType; use Miracode\StripeBundle\StripeException; +use Stripe\Error\SignatureVerification; +use Stripe\Webhook; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -28,6 +30,28 @@ public function handleAction(Request $request) if ($requestData->object !== StripeObjectType::EVENT) { throw new StripeException('Unknown stripe object type in webhook'); } + + // secure webhook with event signature: https://stripe.com/docs/webhooks/signatures + $webhookSecret = $this->getParameter('miracode_stripe.webhook_secret'); + if($webhookSecret !== null) { + $sigHeader = $request->headers->get('Stripe-Signature'); + try { + $event = \Stripe\Webhook::constructEvent( + $request->getContent(), $sigHeader, $webhookSecret + ); + } catch(\UnexpectedValueException $e) { + // Invalid payload + throw new StripeException( + sprintf('Invalid event payload', $requestData->id) + ); + } catch(\Stripe\Error\SignatureVerification $e) { + // Invalid signature + throw new StripeException( + sprintf('Invalid event signature', $requestData->id) + ); + } + } + $stripeEventApi = new StripeEventApi(); if (!$stripeEventObject = $stripeEventApi->retrieve($requestData->id)) { throw new StripeException( diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index f11f9a2..a149f45 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -28,6 +28,9 @@ public function getConfigTreeBuilder() ->isRequired() ->cannotBeEmpty() ->end() + ->scalarNode('webhook_secret') + ->defaultNull() + ->end() ->arrayNode('database') ->children() ->scalarNode('driver') diff --git a/DependencyInjection/MiracodeStripeExtension.php b/DependencyInjection/MiracodeStripeExtension.php index 7f6e7b0..9045a15 100644 --- a/DependencyInjection/MiracodeStripeExtension.php +++ b/DependencyInjection/MiracodeStripeExtension.php @@ -35,6 +35,11 @@ public function load(array $configs, ContainerBuilder $container) $config['secret_key'] ); + $container->setParameter( + 'miracode_stripe.webhook_secret', + $config['webhook_secret'] + ); + if (!empty($config['database']) && !empty($config['database']['model'])) { if (!empty($config['database']['model_transformer'])) { $container->setAlias( diff --git a/Tests/DependencyInjection/MiracodeStripeExtensionTest.php b/Tests/DependencyInjection/MiracodeStripeExtensionTest.php index 6f9fc1f..52f4bd2 100644 --- a/Tests/DependencyInjection/MiracodeStripeExtensionTest.php +++ b/Tests/DependencyInjection/MiracodeStripeExtensionTest.php @@ -31,6 +31,18 @@ public function testStripeSecretKey() ); } + public function testStripeWebhookSecret() + { + $config = $this->getSimpleConfig(); + $container = new ContainerBuilder(); + $extension = new MiracodeStripeExtension(); + $extension->load($config, $container); + $this->assertEquals( + $config['miracode_stripe']['webhook_secret'], + $container->getParameter('miracode_stripe.webhook_secret') + ); + } + public function testConfigWithoutDatabase() { $config = $this->getSimpleConfig(); @@ -108,6 +120,7 @@ protected function getSimpleConfig() $yaml = << Date: Mon, 19 Nov 2018 20:22:58 +0000 Subject: [PATCH 03/61] Added check for Test webhook events and return 200 code. --- Controller/WebhookController.php | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Controller/WebhookController.php b/Controller/WebhookController.php index 5461e2c..d51ba7b 100644 --- a/Controller/WebhookController.php +++ b/Controller/WebhookController.php @@ -23,20 +23,27 @@ class WebhookController extends Controller */ public function handleAction(Request $request) { + $requestData = json_decode($request->getContent()); if (!isset($requestData->id) || !isset($requestData->object)) { throw new BadRequestHttpException('Invalid webhook request data'); } + + // If event id ends with 14 zero's then it is a test webhook event. Return 200 status. + if(substr($requestData->id, -14 ) == "00000000000000"){ + return new Response('Webhook test successful', 200); + } + if ($requestData->object !== StripeObjectType::EVENT) { throw new StripeException('Unknown stripe object type in webhook'); } - // secure webhook with event signature: https://stripe.com/docs/webhooks/signatures + // Secure webhook with event signature: https://stripe.com/docs/webhooks/signatures $webhookSecret = $this->getParameter('miracode_stripe.webhook_secret'); if($webhookSecret !== null) { $sigHeader = $request->headers->get('Stripe-Signature'); try { - $event = \Stripe\Webhook::constructEvent( + $event = Webhook::constructEvent( $request->getContent(), $sigHeader, $webhookSecret ); } catch(\UnexpectedValueException $e) { @@ -44,7 +51,7 @@ public function handleAction(Request $request) throw new StripeException( sprintf('Invalid event payload', $requestData->id) ); - } catch(\Stripe\Error\SignatureVerification $e) { + } catch(SignatureVerification $e) { // Invalid signature throw new StripeException( sprintf('Invalid event signature', $requestData->id) @@ -53,6 +60,7 @@ public function handleAction(Request $request) } $stripeEventApi = new StripeEventApi(); + if (!$stripeEventObject = $stripeEventApi->retrieve($requestData->id)) { throw new StripeException( sprintf('Event does not exists, id %s', $requestData->id) From a36022db3c0420405a711258562f2d2bc265ce7b Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Mon, 19 Nov 2018 20:23:49 +0000 Subject: [PATCH 04/61] Add stripe invoice.finalized as a webhook event type constant --- Event/StripeEvent.php | 1 + 1 file changed, 1 insertion(+) diff --git a/Event/StripeEvent.php b/Event/StripeEvent.php index b7f6c6a..f612910 100644 --- a/Event/StripeEvent.php +++ b/Event/StripeEvent.php @@ -31,6 +31,7 @@ class StripeEvent extends Event const CUSTOMER_SUBSCRIPTION_UPDATED = 'stripe.customer.subscription.updated'; const CUSTOMER_SUBSCRIPTION_TRAIL_WILL_END = 'stripe.customer.subscription.trial_will_end'; const INVOICE_CREATED = 'stripe.invoice.created'; + const INVOICE_FINALIZED = 'stripe.invoice.finalized'; const INVOICE_PAYMENT_FAILED = 'stripe.invoice.payment_failed'; const INVOICE_PAYMENT_SUCCEEDED = 'stripe.invoice.payment_succeeded'; const INVOICE_SENT = 'stripe.invoice.sent'; From 03c685bb2dd1084db0c994a80e69c51d005047e0 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Mon, 19 Nov 2018 20:24:52 +0000 Subject: [PATCH 05/61] Add invoice.finalized to subscriber. --- EventListener/StripeEventSubscriber.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/EventListener/StripeEventSubscriber.php b/EventListener/StripeEventSubscriber.php index b0b4d19..592bed3 100644 --- a/EventListener/StripeEventSubscriber.php +++ b/EventListener/StripeEventSubscriber.php @@ -46,6 +46,7 @@ public static function getSubscribedEvents() StripeEvent::CUSTOMER_SUBSCRIPTION_UPDATED => 'onStripeEvent', StripeEvent::CUSTOMER_SUBSCRIPTION_TRAIL_WILL_END => 'onStripeEvent', StripeEvent::INVOICE_CREATED => 'onStripeEvent', + StripeEvent::INVOICE_FINALIZED => 'onStripeEvent', StripeEvent::INVOICE_PAYMENT_FAILED => 'onStripeEvent', StripeEvent::INVOICE_PAYMENT_SUCCEEDED => 'onStripeEvent', StripeEvent::INVOICE_SENT => 'onStripeEvent', @@ -70,6 +71,7 @@ public static function getSubscribedEvents() public function onStripeEvent(StripeEvent $event) { $object = $event->getDataObject(); + if ($this->modelManager->support($object)) { $this->modelManager->save($object, true); } From d9e24b383aec08c8925fe5e5e842f6c781c45301 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Mon, 19 Nov 2018 20:26:42 +0000 Subject: [PATCH 06/61] Updated Plans and Products to new objects --- Resources/config/doctrine/model/AbstractPlanModel.orm.xml | 2 ++ Resources/config/doctrine/model/AbstractProductModel.orm.xml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Resources/config/doctrine/model/AbstractPlanModel.orm.xml b/Resources/config/doctrine/model/AbstractPlanModel.orm.xml index 86197fc..29e6da2 100644 --- a/Resources/config/doctrine/model/AbstractPlanModel.orm.xml +++ b/Resources/config/doctrine/model/AbstractPlanModel.orm.xml @@ -12,9 +12,11 @@ + + diff --git a/Resources/config/doctrine/model/AbstractProductModel.orm.xml b/Resources/config/doctrine/model/AbstractProductModel.orm.xml index f01addb..f966996 100644 --- a/Resources/config/doctrine/model/AbstractProductModel.orm.xml +++ b/Resources/config/doctrine/model/AbstractProductModel.orm.xml @@ -3,7 +3,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> - + From 7552cdc3f7b0868e6c82de4d1f6da2ac40936e2e Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Mon, 19 Nov 2018 20:27:14 +0000 Subject: [PATCH 07/61] Added nickname and active to plan types --- DependencyInjection/Configuration.php | 3 + .../MiracodeStripeExtension.php | 6 +- Model/AbstractPlanModel.php | 59 +++ README.md | 8 + .../model/AbstractSubscriptionModel.orm.xml | 8 +- Resources/config/services.xml | 3 + Stripe/StripeClient.php | 373 ++++++++++++++++++ 7 files changed, 455 insertions(+), 5 deletions(-) create mode 100644 Stripe/StripeClient.php diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index a149f45..4bc4716 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -31,6 +31,9 @@ public function getConfigTreeBuilder() ->scalarNode('webhook_secret') ->defaultNull() ->end() + ->booleanNode('use_bundle_subscriber') + ->defaultTrue() + ->end() ->arrayNode('database') ->children() ->scalarNode('driver') diff --git a/DependencyInjection/MiracodeStripeExtension.php b/DependencyInjection/MiracodeStripeExtension.php index 9045a15..2b394e7 100644 --- a/DependencyInjection/MiracodeStripeExtension.php +++ b/DependencyInjection/MiracodeStripeExtension.php @@ -53,7 +53,11 @@ public function load(array $configs, ContainerBuilder $container) ); } if ($this->configureDatabase($config['database'], $container)) { - $loader->load('listener.xml'); + + // If the bundle event listener is to be used. + if($config['use_bundle_subscriber'] === true) { + $loader->load('listener.xml'); + } } } } diff --git a/Model/AbstractPlanModel.php b/Model/AbstractPlanModel.php index b96b3c4..5051048 100644 --- a/Model/AbstractPlanModel.php +++ b/Model/AbstractPlanModel.php @@ -62,6 +62,13 @@ abstract class AbstractPlanModel extends StripeModel */ protected $name; + /** + * @StripeObjectParam(name="nickname") + * + * @var string + */ + protected $nickname; + /** * @StripeObjectParam(name="statement_descriptor") * @@ -76,6 +83,13 @@ abstract class AbstractPlanModel extends StripeModel */ protected $trialPeriodDays; + /** + * @StripeObjectParam + * + * @var bool + */ + protected $active; + /** * @return int */ @@ -275,4 +289,49 @@ public function setTrialPeriodDays($trialPeriodDays) return $this; } + + /** + * @return string + */ + public function getNickname(): ?string + { + return $this->nickname; + } + + /** + * Set Nickname. + * + * @param string $nickname + * + * @return AbstractPlanModel + */ + public function setNickname(string $nickname): AbstractPlanModel + { + $this->nickname = $nickname; + + return $this; + } + + /** + * @return bool + */ + public function isActive(): bool + { + return $this->active; + } + + /** + * Set Active. + * + * @param bool $active + * + * @return AbstractPlanModel + */ + public function setActive(bool $active): AbstractPlanModel + { + $this->active = $active; + + return $this; + } + } diff --git a/README.md b/README.md index 0886182..be9c54e 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,14 @@ miracode_stripe: resource: '@MiracodeStripeBundle/Resources/config/routing.xml' ``` +To implement webhook security add the Stripe generated signing secret key to the configration + +``` yaml +# app/config/config.yml (or config/packages/miracode_stripe.yaml for Symfony >=3.4) +miracode_stripe: + webhook_secret: '%webhook_secret_key' +``` + This will register route with url `/stripe/webhook`. You should add this webhook endpoint in Stripe Dashboard. Finally you will be able to listen all Stripe events. For example for stripe event `charge.succeeded` webhook controller will dispatch event `stripe.charge.succeeded`. diff --git a/Resources/config/doctrine/model/AbstractSubscriptionModel.orm.xml b/Resources/config/doctrine/model/AbstractSubscriptionModel.orm.xml index bc3eff0..aed468d 100644 --- a/Resources/config/doctrine/model/AbstractSubscriptionModel.orm.xml +++ b/Resources/config/doctrine/model/AbstractSubscriptionModel.orm.xml @@ -4,7 +4,7 @@ xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> - + @@ -18,12 +18,12 @@ - - + + - + diff --git a/Resources/config/services.xml b/Resources/config/services.xml index 8c3bde0..b24dd60 100644 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -8,6 +8,9 @@ + + + diff --git a/Stripe/StripeClient.php b/Stripe/StripeClient.php new file mode 100644 index 0000000..985c972 --- /dev/null +++ b/Stripe/StripeClient.php @@ -0,0 +1,373 @@ + $paymentToken, + 'email' => $customerEmail + ]); + + $data = [ + 'customer' => $customer->id, + 'plan' => $planId, + ]; + + if ($couponId) { + $data['coupon'] = $couponId; + } + + $subscription = Subscription::create($data); + + return $customer; + } + + /** + * Associate an existing Customer object to an existing Plan. + * + * @throws HttpException: + * - If the customerId is invalid (the customer does not exists...) + * - If the planId is invalid (the plan does not exists...) + * + * @see https://stripe.com/docs/api#create_subscription + * + * @param string $customerId: The customer ID as defined in your Stripe dashboard + * @param string $planId: The plan ID as defined in your Stripe dashboard + * @param array $parameters: Optional additional parameters, the complete list is available here: https://stripe.com/docs/api#create_subscription + * + * @return Subscription + */ + public function subscribeExistingCustomerToPlan($customerId, $planId, $parameters = []) + { + $data = [ + 'customer' => $customerId, + 'plan' => $planId + ]; + + if ($parameters && is_array($parameters)) { + $data = array_merge($parameters, $data); + } + + return Subscription::create($data); + } + + /** + * Create a new Charge from a payment token, to an optional connected stripe account, with an optional application fee. + * + * @throws HttpException: + * - If the payment token is invalid (payment failed) + * + * @see https://stripe.com/docs/charges + * + * @param int $chargeAmount: The charge amount in cents + * @param string $chargeCurrency: The charge currency to use + * @param string $paymentToken: The payment token returned by the payment form (Stripe.js) + * @param string $stripeAccountId: The connected stripe account ID + * @param int $applicationFee: The fee taken by the platform, in cents + * @param string $description: An optional charge description + * @param array $metadata: An optional array of metadatas + * + * @return Charge + */ + public function createCharge($chargeAmount, $chargeCurrency, $paymentToken, $stripeAccountId = null, $applicationFee = 0, $chargeDescription = '', $chargeMetadata = []) + { + $chargeOptions = [ + 'amount' => $chargeAmount, + 'currency' => $chargeCurrency, + 'source' => $paymentToken, + 'description' => $chargeDescription, + 'metadata' => $chargeMetadata + ]; + + if ($applicationFee && intval($applicationFee) > 0) { + $chargeOptions['application_fee'] = intval($applicationFee); + } + + $connectedAccountOptions = []; + + if ($stripeAccountId) { + $connectedAccountOptions['stripe_account'] = $stripeAccountId; + } + + return Charge::create($chargeOptions, $connectedAccountOptions); + } + + /** + * Create a new Destination Charge from a payment token, to a connected stripe account, with an application fee. + * + * @throws HttpException: + * - If the payment token is invalid (payment failed) + * + * @see https://stripe.com/docs/connect/destination-charges + * + * @param int $chargeAmount: The charge amount in cents + * @param string $chargeCurrency: The charge currency to use + * @param string $paymentToken: The payment token returned by the payment form (Stripe.js) + * @param string $stripeAccountId: The connected stripe account ID + * @param int $applicationFee: The fee taken by the platform, in cents + * @param string $chargeDescription: An optional charge description + * @param array $chargeMetadata: An optional array of metadatas + * + * @return Charge + */ + public function createDestinationCharge($chargeAmount, $chargeCurrency, $paymentToken, $stripeAccountId, $applicationFee, $chargeDescription = '', $chargeMetadata = []) + { + $chargeOptions = [ + 'amount' => $chargeAmount, + 'currency' => $chargeCurrency, + 'source' => $paymentToken, + 'description' => $chargeDescription, + 'metadata' => $chargeMetadata, + 'destination' => [ + 'amount' => $chargeAmount - $applicationFee, + 'account' => $stripeAccountId + ] + ]; + + return Charge::create($chargeOptions); + } + + /** + * Create a new Charge from a payment token, to an optional connected stripe account, with an optional application fee. + * + * @throws HttpException: + * - If the payment token is invalid (payment failed) + * + * @see https://stripe.com/docs/charges#saving-credit-card-details-for-later + * + * @param string $paymentToken: The payment token returned by the payment form (Stripe.js) + * @param string $email: An optional customer e-mail + * @param array $parameters: Optional additional parameters, the complete list is available here: https://stripe.com/docs/api#create_customer + * + * @return Charge + */ + public function createCustomer($paymentToken, $email = null, $parameters = []) + { + $data = [ + 'source' => $paymentToken, + 'email' => $email + ]; + + if ($parameters && is_array($parameters)) { + $data = array_merge($parameters, $data); + } + + return Customer::create($data); + } + + /** + * Create a new Charge on an existing Customer object, to an optional connected stripe account, with an optional application fee + * + * @throws HttpException: + * - If the payment token is invalid (payment failed) + * + * @see https://stripe.com/docs/charges#saving-credit-card-details-for-later + * + * @param int $chargeAmount: The charge amount in cents + * @param string $chargeCurrency: The charge currency to use + * @param string $customerId: The Stripe Customer object ID + * @param string $stripeAccountId: The connected stripe account ID + * @param int $applicationFee: The fee taken by the platform, in cents + * @param string $description: An optional charge description + * @param array $metadata: An optional array of metadatas + * + * @return Charge + */ + public function chargeCustomer($chargeAmount, $chargeCurrency, $customerId, $stripeAccountId = null, $applicationFee = 0, $chargeDescription = '', $chargeMetadata = []) + { + $chargeOptions = [ + 'amount' => $chargeAmount, + 'currency' => $chargeCurrency, + 'customer' => $customerId, + 'description' => $chargeDescription, + 'metadata' => $chargeMetadata + ]; + + if ($applicationFee && intval($applicationFee) > 0) { + $chargeOptions['application_fee'] = intval($applicationFee); + } + + $connectedAccountOptions = []; + + if ($stripeAccountId) { + $connectedAccountOptions['stripe_account'] = $stripeAccountId; + } + + return Charge::create($chargeOptions, $connectedAccountOptions); + } + + /** + * Create a new Refund on an existing Charge (by its ID). + * + * @throws HttpException: + * - If the charge id is invalid (the charge does not exists...) + * - If the charge has already been refunded + * + * @see https://stripe.com/docs/connect/direct-charges#issuing-refunds + * + * @param string $chargeId: The charge ID + * @param int $refundAmount: The charge amount in cents + * @param array $metadata: optional additional informations about the refund + * @param string $reason: The reason of the refund, either "requested_by_customer", "duplicate" or "fraudulent" + * @param bool $refundApplicationFee: Wether the application_fee should be refunded aswell. + * @param bool $reverseTransfer: Wether the transfer should be reversed + * @param string $stripeAccountId: The optional connected stripe account ID on which charge has been made. + * + * @return Refund + */ + public function refundCharge($chargeId, $refundAmount = null, $metadata = [], $reason = 'requested_by_customer', $refundApplicationFee = true, $reverseTransfer = false, $stripeAccountId = null) + { + $refundOptions = [ + 'charge' => $chargeId, + 'metadata' => $metadata, + 'reason' => $reason, + 'refund_application_fee' => (bool) $refundApplicationFee, + 'reverse_transfer' => (bool) $reverseTransfer + ]; + + if ($refundAmount) { + $refundOptions['amount'] = intval($refundAmount); + } + + $connectedAccountOptions = []; + + if ($stripeAccountId) { + $connectedAccountOptions['stripe_account'] = $stripeAccountId; + } + + return Refund::create($refundOptions, $connectedAccountOptions); + } +} From 7e58e3ccd748c6ed334601f9bbcd81179384f7c1 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Mon, 19 Nov 2018 20:28:13 +0000 Subject: [PATCH 08/61] Revert "Added nickname and active to plan types" --- Model/AbstractPlanModel.php | 59 ------------------------------------- 1 file changed, 59 deletions(-) diff --git a/Model/AbstractPlanModel.php b/Model/AbstractPlanModel.php index 5051048..b96b3c4 100644 --- a/Model/AbstractPlanModel.php +++ b/Model/AbstractPlanModel.php @@ -62,13 +62,6 @@ abstract class AbstractPlanModel extends StripeModel */ protected $name; - /** - * @StripeObjectParam(name="nickname") - * - * @var string - */ - protected $nickname; - /** * @StripeObjectParam(name="statement_descriptor") * @@ -83,13 +76,6 @@ abstract class AbstractPlanModel extends StripeModel */ protected $trialPeriodDays; - /** - * @StripeObjectParam - * - * @var bool - */ - protected $active; - /** * @return int */ @@ -289,49 +275,4 @@ public function setTrialPeriodDays($trialPeriodDays) return $this; } - - /** - * @return string - */ - public function getNickname(): ?string - { - return $this->nickname; - } - - /** - * Set Nickname. - * - * @param string $nickname - * - * @return AbstractPlanModel - */ - public function setNickname(string $nickname): AbstractPlanModel - { - $this->nickname = $nickname; - - return $this; - } - - /** - * @return bool - */ - public function isActive(): bool - { - return $this->active; - } - - /** - * Set Active. - * - * @param bool $active - * - * @return AbstractPlanModel - */ - public function setActive(bool $active): AbstractPlanModel - { - $this->active = $active; - - return $this; - } - } From 44da331ec12da5cfb41d104ce8f54adccd4632ff Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Mon, 19 Nov 2018 20:31:16 +0000 Subject: [PATCH 09/61] Add an wrapper for the Client --- Stripe/StripeClient.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Stripe/StripeClient.php b/Stripe/StripeClient.php index 985c972..98c126e 100644 --- a/Stripe/StripeClient.php +++ b/Stripe/StripeClient.php @@ -1,7 +1,8 @@ Date: Mon, 19 Nov 2018 20:31:52 +0000 Subject: [PATCH 10/61] Add the StripeClient as a service --- Resources/config/services.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/Resources/config/services.xml b/Resources/config/services.xml index b24dd60..8c3bde0 100644 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -8,9 +8,6 @@ - - - From e4198409d1256e29957fa3180be262c80caa9e66 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Mon, 19 Nov 2018 20:32:13 +0000 Subject: [PATCH 11/61] Fix decimal type --- .../doctrine/model/AbstractSubscriptionModel.orm.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Resources/config/doctrine/model/AbstractSubscriptionModel.orm.xml b/Resources/config/doctrine/model/AbstractSubscriptionModel.orm.xml index aed468d..bc3eff0 100644 --- a/Resources/config/doctrine/model/AbstractSubscriptionModel.orm.xml +++ b/Resources/config/doctrine/model/AbstractSubscriptionModel.orm.xml @@ -4,7 +4,7 @@ xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> - + @@ -18,12 +18,12 @@ - - + + - + From 4b4fa0e4d032f45e74dc037e46d5cbc31338dd8b Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Mon, 19 Nov 2018 20:33:19 +0000 Subject: [PATCH 12/61] Make definition of the webhook subscriber optional from the config. This allows the main app bundle to extend and override the subscriber with their own. --- DependencyInjection/Configuration.php | 3 --- DependencyInjection/MiracodeStripeExtension.php | 6 +----- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 4bc4716..a149f45 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -31,9 +31,6 @@ public function getConfigTreeBuilder() ->scalarNode('webhook_secret') ->defaultNull() ->end() - ->booleanNode('use_bundle_subscriber') - ->defaultTrue() - ->end() ->arrayNode('database') ->children() ->scalarNode('driver') diff --git a/DependencyInjection/MiracodeStripeExtension.php b/DependencyInjection/MiracodeStripeExtension.php index 2b394e7..9045a15 100644 --- a/DependencyInjection/MiracodeStripeExtension.php +++ b/DependencyInjection/MiracodeStripeExtension.php @@ -53,11 +53,7 @@ public function load(array $configs, ContainerBuilder $container) ); } if ($this->configureDatabase($config['database'], $container)) { - - // If the bundle event listener is to be used. - if($config['use_bundle_subscriber'] === true) { - $loader->load('listener.xml'); - } + $loader->load('listener.xml'); } } } From f21bcc9e2a4f7bacec1c35ab94595de5855685b0 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Mon, 19 Nov 2018 22:14:07 +0000 Subject: [PATCH 13/61] Make definition of the webhook subscriber optional from the config. This allows the main app bundle to extend and override the subscriber with their own. --- DependencyInjection/Configuration.php | 3 +++ DependencyInjection/MiracodeStripeExtension.php | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index a149f45..4bc4716 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -31,6 +31,9 @@ public function getConfigTreeBuilder() ->scalarNode('webhook_secret') ->defaultNull() ->end() + ->booleanNode('use_bundle_subscriber') + ->defaultTrue() + ->end() ->arrayNode('database') ->children() ->scalarNode('driver') diff --git a/DependencyInjection/MiracodeStripeExtension.php b/DependencyInjection/MiracodeStripeExtension.php index 9045a15..2b394e7 100644 --- a/DependencyInjection/MiracodeStripeExtension.php +++ b/DependencyInjection/MiracodeStripeExtension.php @@ -53,7 +53,11 @@ public function load(array $configs, ContainerBuilder $container) ); } if ($this->configureDatabase($config['database'], $container)) { - $loader->load('listener.xml'); + + // If the bundle event listener is to be used. + if($config['use_bundle_subscriber'] === true) { + $loader->load('listener.xml'); + } } } } From d085824a6de1e5d0401c662221f327bc63578477 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Mon, 19 Nov 2018 22:31:29 +0000 Subject: [PATCH 14/61] Update service definition. Update readme --- README.md | 78 ++++++++++++++++++++++++++++++----- Resources/config/services.xml | 3 ++ 2 files changed, 71 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index be9c54e..a386bc2 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,19 @@ $customer = \Stripe\Customer::create([ 'email' => 'newcustomer@example.com' ]); ``` +or inject the StripeClient + +``` php +protected $stripeClient; + +public function __construct(\Miracode\StripeBundle\Stripe\StripeClient $stripeClient){ + $this->stripeClient = $stripeClient; +} + +public function yourMethod(){ + $customer = $this->stripeClient->retrieveCustomer($stripeCustomerId) +} +``` ####Stripe Events @@ -72,14 +85,6 @@ miracode_stripe: resource: '@MiracodeStripeBundle/Resources/config/routing.xml' ``` -To implement webhook security add the Stripe generated signing secret key to the configration - -``` yaml -# app/config/config.yml (or config/packages/miracode_stripe.yaml for Symfony >=3.4) -miracode_stripe: - webhook_secret: '%webhook_secret_key' -``` - This will register route with url `/stripe/webhook`. You should add this webhook endpoint in Stripe Dashboard. Finally you will be able to listen all Stripe events. For example for stripe event `charge.succeeded` webhook controller will dispatch event `stripe.charge.succeeded`. @@ -99,7 +104,7 @@ class StripeSubscriber implements EventSubscriberInterface public static function getSubscribedEvents() { return [ - 'stripe.charge.succeeded' => 'onChargeSucceededEvent', + StripeEvent::CHARGE_SUCCEEDED => 'onChargeSucceededEvent', ]; } @@ -108,11 +113,63 @@ class StripeSubscriber implements EventSubscriberInterface public function onChargeSucceededEvent(StripeEvent $event) { $stripeEvent = $event->getEvent(); //Stripe event object (instanceof \Stripe\Event) - $charge = $event->getObjectData(); //Stripe charge object (instanceof \Stripe\Charge) + $charge = $event->getDataObject(); //Stripe charge object (instanceof \Stripe\Charge) } } ``` +For more customised functions you can ignore and extend the bundle subscriber with your own for custom functionality. + +First ignore the default subscriber in the bundle config. +``` yaml +# app/config/config.yml (or config/packages/miracode_stripe.yaml for Symfony >=3.4) +miracode_stripe: + secret_key: "%stripe_secret_key%" + use_bundle_subscriber: false +``` +Then create your own subscriber that extends the bundle subscriber. (Autowire or declare the new subscriber) +``` php +// AppBundle/EventListener/StripeEventSubscriber.php + +namespace App\EventListener; + +use Miracode\StripeBundle\Event\StripeEvent; +use Miracode\StripeBundle\EventListener\StripeEventSubscriber as MiracodeStripeEventSubscriber +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +class StripeEventSubscriber extends MiracodeStripeEventSubscriber implements EventSubscriberInterface +{ + public function __construct($modelManager){ + parent::__construct($modelManager); + } + + public static function getSubscribedEvents() + { + // Get the Stripe Bundle default subscribed events. + $parentSubscribedEvents = parent::getSubscribedEvents(); + + // Add/Overwrite events for this application + $overideEvents = [ + StripeEvent::INVOICE_UPCOMING => 'onInvoiceUpcoming', + ]; + + // Merge the array, replacing the original events. + $subscribedEvents = array_replace($parentSubscribedEvents, $overideEvents); + + return $subscribedEvents; + } + + //[...] + + public function onInvoiceUpcoming(StripeEvent $event) + { + $stripeEvent = $event->getEvent(); //Stripe event object (instanceof \Stripe\Event) + $charge = $event->getDataObject(); //Stripe charge object (instanceof \Stripe\Charge) + } +} +``` + + ####Saving stripe data in database Now only Doctrine ORM driver is available. @@ -125,6 +182,7 @@ In bundle there are abstract entity classes with orm mapping for main stripe obj - customer: `Miracode\StripeBundle\Model\AbstractCustomerModel` - invoice: `Miracode\StripeBundle\Model\AbstractInvoiceModel` - plan: `Miracode\StripeBundle\Model\AbstractPlanModel` + - product: `Miracode\StripeBundle\Model\AbstractProductModel` - refund: `Miracode\StripeBundle\Model\AbstractRefundModel` - subscription: `Miracode\StripeBundle\Model\AbstractSubscriptionModel` diff --git a/Resources/config/services.xml b/Resources/config/services.xml index 8c3bde0..b24dd60 100644 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -8,6 +8,9 @@ + + + From fbf37b65ab2464a4007dcbd521e441e69cc03257 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Mon, 19 Nov 2018 22:34:34 +0000 Subject: [PATCH 15/61] Redefine nickname --- Model/AbstractPlanModel.php | 59 +++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/Model/AbstractPlanModel.php b/Model/AbstractPlanModel.php index b96b3c4..5051048 100644 --- a/Model/AbstractPlanModel.php +++ b/Model/AbstractPlanModel.php @@ -62,6 +62,13 @@ abstract class AbstractPlanModel extends StripeModel */ protected $name; + /** + * @StripeObjectParam(name="nickname") + * + * @var string + */ + protected $nickname; + /** * @StripeObjectParam(name="statement_descriptor") * @@ -76,6 +83,13 @@ abstract class AbstractPlanModel extends StripeModel */ protected $trialPeriodDays; + /** + * @StripeObjectParam + * + * @var bool + */ + protected $active; + /** * @return int */ @@ -275,4 +289,49 @@ public function setTrialPeriodDays($trialPeriodDays) return $this; } + + /** + * @return string + */ + public function getNickname(): ?string + { + return $this->nickname; + } + + /** + * Set Nickname. + * + * @param string $nickname + * + * @return AbstractPlanModel + */ + public function setNickname(string $nickname): AbstractPlanModel + { + $this->nickname = $nickname; + + return $this; + } + + /** + * @return bool + */ + public function isActive(): bool + { + return $this->active; + } + + /** + * Set Active. + * + * @param bool $active + * + * @return AbstractPlanModel + */ + public function setActive(bool $active): AbstractPlanModel + { + $this->active = $active; + + return $this; + } + } From 29574739c0a6a13b6c4237d2eff11acec9ce885b Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Tue, 20 Nov 2018 12:29:02 +0000 Subject: [PATCH 16/61] Add Products and Subscription Items to the StripeClient --- Resources/config/services.xml | 2 +- Stripe/StripeClient.php | 150 +++++++++++++++++++++++++++++++++- 2 files changed, 148 insertions(+), 4 deletions(-) diff --git a/Resources/config/services.xml b/Resources/config/services.xml index b24dd60..76d8dd4 100644 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -9,7 +9,7 @@ class="Miracode\StripeBundle\Transformer\AnnotationTransformer"> - + %miracode_stripe.secret_key% diff --git a/Stripe/StripeClient.php b/Stripe/StripeClient.php index 98c126e..9c401ee 100644 --- a/Stripe/StripeClient.php +++ b/Stripe/StripeClient.php @@ -14,7 +14,9 @@ Stripe\Customer, Stripe\Coupon, Stripe\Plan, + Stripe\Product, Stripe\Subscription, + Stripe\SubscriptionItem, Stripe\Refund; /** @@ -95,13 +97,27 @@ public function retrieveCustomer($customerId) * * @param string $customerId: The customer ID * - * @return Customer + * @return Subscription */ public function retrieveSubscription($subscriptionId) { return Subscription::retrieve($subscriptionId); } + /** + * Retrieve a SubscriptionItem instance by its ID + * + * @throws HttpException: + * - If the customerId is invalid + * + * @param $subscriptionItemId + * @return SubscriptionItem + */ + public function retrieveSubscriptionItem($subscriptionItemId) + { + return SubscriptionItem::retrieve($subscriptionItemId); + } + /** * Retrieve a Charge instance by its ID * @@ -178,7 +194,58 @@ public function subscribeExistingCustomerToPlan($customerId, $planId, $parameter 'plan' => $planId ]; - if ($parameters && is_array($parameters)) { + if (is_array($parameters) && !empty($parameters)) { + $data = array_merge($parameters, $data); + } + + return Subscription::create($data); + } + + /** + * Associate an existing Customer object to an existing Plan. + * + * @throws HttpException: + * - If the customerId is invalid (the customer does not exists...) + * - If the planId is invalid (the plan does not exists...) + * + * @see https://stripe.com/docs/api#create_subscription + * + * @param string $customerId: The customer ID as defined in your Stripe dashboard + * @param array $items: An Array of Plan items. + * @param array $parameters: Optional additional parameters, the complete list is available here: https://stripe.com/docs/api#create_subscription + * + * @return Subscription + */ + public function subscribeExistingCustomerToMultiplePlans($customerId, $items = [], $parameters = []) + { + $data = [ + 'customer' => $customerId, + 'items' => $items + ]; + + if (is_array($parameters) && !empty($parameters)) { + $data = array_merge($parameters, $data); + } + + return Subscription::create($data); + } + + /** + * @param $subscriptionId + * @param $planId + * @param $quantity + * @param array $parameters + * @return SubscriptionItem + */ + public function createSubscriptionItem($subscriptionId, $planId, $quantity, $parameters = []) + { + $data = [ + "subscription" => $subscriptionId, + "plan" => $planId, + "quantity" => $quantity, + ]; + + if (is_array($parameters) && !empty($parameters)) { $data = array_merge($parameters, $data); } @@ -282,7 +349,7 @@ public function createCustomer($paymentToken, $email = null, $parameters = []) 'email' => $email ]; - if ($parameters && is_array($parameters)) { + if (is_array($parameters) && !empty($parameters)) { $data = array_merge($parameters, $data); } @@ -371,4 +438,81 @@ public function refundCharge($chargeId, $refundAmount = null, $metadata = [], $r return Refund::create($refundOptions, $connectedAccountOptions); } + + /** + * @param string $name Product Name + * @param string $type 'service' or 'goods' + * @param array $parameters Array of additional parameters to pass to the constructor + * @return Product + */ + public function createProduct($name, $type, $parameters =[] ) + { + $data = [ + 'name' => $name, + 'type' => $type, + ]; + + if (is_array($parameters) && !empty($parameters)) { + $data = array_merge($parameters, $data); + } + + return Product::create($data); + } + + /** + * @param string $productId + * @param string $interval + * @param null $currency Currency to billin , defaults to 'eur' + * @param array $parameters + * @return Plan + */ + public function createPlan($productId, $interval, $currency = null, $parameters = [] ) + { + + if($currency === null){ + $currency = 'eur'; + } + + $data = [ + 'product' => $productId, + 'interval' => $interval, + 'currency' =>$currency, + ]; + + if (is_array($parameters) && !empty($parameters)) { + $data = array_merge($parameters, $data); + } + + return Plan::create($data); + + } + + /** + * @param string $id + * @param string $duration + * @param bool $isPercentage True = percentage_type deduction, false = amount_type + * @param int|float $discount The percentage discount, or amount discount + * @param array $parameters Additional parameters to pass to the constructor + * @return Coupon + */ + public function createCoupon($id, $duration, $isPercentage = true, $discount, $parameters = []) + { + + $data = [ + "id" => $id, + "duration" => $duration, + ]; + + if($isPercentage){ + $data['percent_off'] = $discount; + } else { + $data['amount_off'] = $discount; + } + + if (is_array($parameters) && !empty($parameters)) { + $data = array_merge($parameters, $data); + } + + return Coupon::create($data); + } } From e3b74f108d498db15ab93688c67b57afefa80d4e Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Fri, 23 Nov 2018 14:16:14 +0000 Subject: [PATCH 17/61] Add Products and Subscription Items to the StripeClient --- Controller/WebhookController.php | 36 +++++++++---------- Manager/Doctrine/DoctrineORMModelManager.php | 25 +++++++++++-- Manager/ModelManagerInterface.php | 2 +- Model/AbstractCustomerModel.php | 2 +- Model/AbstractPlanModel.php | 1 + Model/AbstractSubscriptionModel.php | 1 + Model/StripeModel.php | 12 +++---- Model/StripeModelInterface.php | 2 +- .../doctrine/model/AbstractCardModel.orm.xml | 7 ++-- .../model/AbstractChargeModel.orm.xml | 5 +-- .../model/AbstractCouponModel.orm.xml | 5 +-- .../model/AbstractCustomerModel.orm.xml | 5 +-- .../model/AbstractInvoiceModel.orm.xml | 5 +-- .../doctrine/model/AbstractPlanModel.orm.xml | 5 +-- .../model/AbstractProductModel.orm.xml | 6 ++-- .../model/AbstractRefundModel.orm.xml | 5 +-- .../model/AbstractSubscriptionModel.orm.xml | 14 +++----- Stripe/StripeClient.php | 21 +++++++++++ 18 files changed, 87 insertions(+), 72 deletions(-) diff --git a/Controller/WebhookController.php b/Controller/WebhookController.php index d51ba7b..4b717ce 100644 --- a/Controller/WebhookController.php +++ b/Controller/WebhookController.php @@ -40,24 +40,24 @@ public function handleAction(Request $request) // Secure webhook with event signature: https://stripe.com/docs/webhooks/signatures $webhookSecret = $this->getParameter('miracode_stripe.webhook_secret'); - if($webhookSecret !== null) { - $sigHeader = $request->headers->get('Stripe-Signature'); - try { - $event = Webhook::constructEvent( - $request->getContent(), $sigHeader, $webhookSecret - ); - } catch(\UnexpectedValueException $e) { - // Invalid payload - throw new StripeException( - sprintf('Invalid event payload', $requestData->id) - ); - } catch(SignatureVerification $e) { - // Invalid signature - throw new StripeException( - sprintf('Invalid event signature', $requestData->id) - ); - } - } +// if($webhookSecret !== null) { +// $sigHeader = $request->headers->get('Stripe-Signature'); +// try { +// $event = Webhook::constructEvent( +// $request->getContent(), $sigHeader, $webhookSecret +// ); +// } catch(\UnexpectedValueException $e) { +// // Invalid payload +// throw new StripeException( +// sprintf('Invalid event payload', $requestData->id) +// ); +// } catch(SignatureVerification $e) { +// // Invalid signature +// throw new StripeException( +// sprintf('Invalid event signature', $requestData->id) +// ); +// } +// } $stripeEventApi = new StripeEventApi(); diff --git a/Manager/Doctrine/DoctrineORMModelManager.php b/Manager/Doctrine/DoctrineORMModelManager.php index 1df472a..51dae97 100644 --- a/Manager/Doctrine/DoctrineORMModelManager.php +++ b/Manager/Doctrine/DoctrineORMModelManager.php @@ -4,6 +4,8 @@ use Doctrine\Common\Persistence\ObjectManager; use Miracode\StripeBundle\Manager\ModelManagerInterface; +use Miracode\StripeBundle\Model\AbstractCustomerModel; +use Miracode\StripeBundle\Model\AbstractProductModel; use Miracode\StripeBundle\Model\SafeDeleteModelInterface; use Miracode\StripeBundle\Model\StripeModelInterface; use Miracode\StripeBundle\StripeException; @@ -68,7 +70,7 @@ public function retrieve(StripeObject $object) $modelClass = $this->modelClass($object); return $this->objectManager->getRepository($modelClass)->findOneBy([ - 'stripeId' => $object->id + 'id' => $object->id ]); } @@ -79,7 +81,7 @@ public function retrieve(StripeObject $object) * @param string $objectType * @return StripeModelInterface|null */ - public function retrieveByStripeId($id, $objectType) + public function retrieveById($id, $objectType) { $stripeObject = new StripeObject($id); $stripeObject->object = $objectType; @@ -201,8 +203,25 @@ protected function modelClass(StripeObject $object) */ protected function createModel(StripeObject $object) { + $className = $this->modelClass($object); + $class = new $className(); + + if($object->id){ + $class->setId($object->id); + } + +// // If the object has a customer then map. +// if($object->customer){ +// $class->setCustomer($this->objectManager->find(AbstractCustomerModel::class, $object->customer)); +// } +// +// // If the object has a has a product then map. +// if($object->product){ +// $class->setCustomer($this->objectManager->find(AbstractProductModel::class, $object->product)); +// } + + return $class; - return new $className(); } } diff --git a/Manager/ModelManagerInterface.php b/Manager/ModelManagerInterface.php index bb38e83..ab78a8f 100644 --- a/Manager/ModelManagerInterface.php +++ b/Manager/ModelManagerInterface.php @@ -32,7 +32,7 @@ public function retrieve(StripeObject $object); * @param string $objectType * @return StripeModelInterface|null */ - public function retrieveByStripeId($id, $objectType); + public function retrieveById($id, $objectType); /** * Save stripe object in database diff --git a/Model/AbstractCustomerModel.php b/Model/AbstractCustomerModel.php index 9e186bf..e91f608 100644 --- a/Model/AbstractCustomerModel.php +++ b/Model/AbstractCustomerModel.php @@ -308,6 +308,6 @@ public function setShipping($shipping) */ public function retrieveStripeObject() { - return \Stripe\Customer::retrieve($this->getStripeId()); + return \Stripe\Customer::retrieve($this->getId()); } } diff --git a/Model/AbstractPlanModel.php b/Model/AbstractPlanModel.php index 5051048..f155a11 100644 --- a/Model/AbstractPlanModel.php +++ b/Model/AbstractPlanModel.php @@ -6,6 +6,7 @@ abstract class AbstractPlanModel extends StripeModel { + /** * @StripeObjectParam * diff --git a/Model/AbstractSubscriptionModel.php b/Model/AbstractSubscriptionModel.php index b7249e2..28335a2 100644 --- a/Model/AbstractSubscriptionModel.php +++ b/Model/AbstractSubscriptionModel.php @@ -6,6 +6,7 @@ abstract class AbstractSubscriptionModel extends StripeModel { + /** * @StripeObjectParam(name="application_fee_percent") * diff --git a/Model/StripeModel.php b/Model/StripeModel.php index a1b87ea..af1f692 100644 --- a/Model/StripeModel.php +++ b/Model/StripeModel.php @@ -11,26 +11,26 @@ class StripeModel implements StripeModelInterface * * @var string */ - protected $stripeId; + protected $id; /** * Retrieve stripe object ID * * @return string */ - public function getStripeId() + public function getId() { - return $this->stripeId; + return $this->id; } /** - * @param string $stripeId + * @param string $id * * @return $this */ - public function setStripeId($stripeId) + public function setId($id) { - $this->stripeId = $stripeId; + $this->id = $id; return $this; } diff --git a/Model/StripeModelInterface.php b/Model/StripeModelInterface.php index 8615873..b6afe05 100644 --- a/Model/StripeModelInterface.php +++ b/Model/StripeModelInterface.php @@ -11,5 +11,5 @@ interface StripeModelInterface * * return string */ - public function getStripeId(); + public function getId(); } diff --git a/Resources/config/doctrine/model/AbstractCardModel.orm.xml b/Resources/config/doctrine/model/AbstractCardModel.orm.xml index 09e3558..f7d9262 100644 --- a/Resources/config/doctrine/model/AbstractCardModel.orm.xml +++ b/Resources/config/doctrine/model/AbstractCardModel.orm.xml @@ -22,13 +22,10 @@ - + - + - - - \ No newline at end of file diff --git a/Resources/config/doctrine/model/AbstractChargeModel.orm.xml b/Resources/config/doctrine/model/AbstractChargeModel.orm.xml index dad023e..b4950c2 100644 --- a/Resources/config/doctrine/model/AbstractChargeModel.orm.xml +++ b/Resources/config/doctrine/model/AbstractChargeModel.orm.xml @@ -29,11 +29,8 @@ - + - - - \ No newline at end of file diff --git a/Resources/config/doctrine/model/AbstractCouponModel.orm.xml b/Resources/config/doctrine/model/AbstractCouponModel.orm.xml index 67c966c..91255b4 100644 --- a/Resources/config/doctrine/model/AbstractCouponModel.orm.xml +++ b/Resources/config/doctrine/model/AbstractCouponModel.orm.xml @@ -14,13 +14,10 @@ - + - - - diff --git a/Resources/config/doctrine/model/AbstractCustomerModel.orm.xml b/Resources/config/doctrine/model/AbstractCustomerModel.orm.xml index f23a7ff..c6b2884 100644 --- a/Resources/config/doctrine/model/AbstractCustomerModel.orm.xml +++ b/Resources/config/doctrine/model/AbstractCustomerModel.orm.xml @@ -15,11 +15,8 @@ - + - - - \ No newline at end of file diff --git a/Resources/config/doctrine/model/AbstractInvoiceModel.orm.xml b/Resources/config/doctrine/model/AbstractInvoiceModel.orm.xml index 8a5338f..ccbe503 100644 --- a/Resources/config/doctrine/model/AbstractInvoiceModel.orm.xml +++ b/Resources/config/doctrine/model/AbstractInvoiceModel.orm.xml @@ -30,7 +30,6 @@ - @@ -38,10 +37,8 @@ + - - - diff --git a/Resources/config/doctrine/model/AbstractPlanModel.orm.xml b/Resources/config/doctrine/model/AbstractPlanModel.orm.xml index 29e6da2..1a8d0ee 100644 --- a/Resources/config/doctrine/model/AbstractPlanModel.orm.xml +++ b/Resources/config/doctrine/model/AbstractPlanModel.orm.xml @@ -14,13 +14,10 @@ - + - - - \ No newline at end of file diff --git a/Resources/config/doctrine/model/AbstractProductModel.orm.xml b/Resources/config/doctrine/model/AbstractProductModel.orm.xml index f966996..6829cb9 100644 --- a/Resources/config/doctrine/model/AbstractProductModel.orm.xml +++ b/Resources/config/doctrine/model/AbstractProductModel.orm.xml @@ -19,10 +19,8 @@ - - - - + + \ No newline at end of file diff --git a/Resources/config/doctrine/model/AbstractRefundModel.orm.xml b/Resources/config/doctrine/model/AbstractRefundModel.orm.xml index f6f8aeb..ca67907 100644 --- a/Resources/config/doctrine/model/AbstractRefundModel.orm.xml +++ b/Resources/config/doctrine/model/AbstractRefundModel.orm.xml @@ -15,11 +15,8 @@ - + - - - \ No newline at end of file diff --git a/Resources/config/doctrine/model/AbstractSubscriptionModel.orm.xml b/Resources/config/doctrine/model/AbstractSubscriptionModel.orm.xml index bc3eff0..476b36b 100644 --- a/Resources/config/doctrine/model/AbstractSubscriptionModel.orm.xml +++ b/Resources/config/doctrine/model/AbstractSubscriptionModel.orm.xml @@ -4,7 +4,7 @@ xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> - + @@ -18,18 +18,14 @@ - - + + - - + - - - - + \ No newline at end of file diff --git a/Stripe/StripeClient.php b/Stripe/StripeClient.php index 9c401ee..afef783 100644 --- a/Stripe/StripeClient.php +++ b/Stripe/StripeClient.php @@ -9,6 +9,7 @@ namespace Miracode\StripeBundle\Stripe; +use Stripe\Card; use Stripe\Stripe, Stripe\Charge, Stripe\Customer, @@ -135,6 +136,24 @@ public function retrieveCharge($chargeId) return Charge::retrieve($chargeId); } + + /** + * Retrieve a Charge instance by its ID + * + * @throws HttpException: + * - If the chargeId is invalid + * + * @see https://stripe.com/docs/api#charges + * + * @param string $chargeId: The charge ID + * + * @return Card + */ + public function retrieveCard($cardId) + { + return Card::retrieve($cardId); + } + /** * Associate a new Customer object to an existing Plan. * @@ -227,6 +246,8 @@ public function subscribeExistingCustomerToMultiplePlans($customerId, $items = [ $data = array_merge($parameters, $data); } + dump($data); + return Subscription::create($data); } From d012ec50ef07e3055e04116e5d3793f6adc8199c Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Fri, 23 Nov 2018 14:16:50 +0000 Subject: [PATCH 18/61] Add Products and Subscription Items to the StripeClient --- Stripe/StripeClient.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/Stripe/StripeClient.php b/Stripe/StripeClient.php index afef783..e692f2b 100644 --- a/Stripe/StripeClient.php +++ b/Stripe/StripeClient.php @@ -246,8 +246,6 @@ public function subscribeExistingCustomerToMultiplePlans($customerId, $items = [ $data = array_merge($parameters, $data); } - dump($data); - return Subscription::create($data); } From 4012da860a1e281e1400bf000830842ceabac17a Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Tue, 2 Jul 2019 00:58:33 +0100 Subject: [PATCH 19/61] Add invoice deleted event --- Event/StripeEvent.php | 1 + 1 file changed, 1 insertion(+) diff --git a/Event/StripeEvent.php b/Event/StripeEvent.php index f612910..4b6d8b0 100644 --- a/Event/StripeEvent.php +++ b/Event/StripeEvent.php @@ -31,6 +31,7 @@ class StripeEvent extends Event const CUSTOMER_SUBSCRIPTION_UPDATED = 'stripe.customer.subscription.updated'; const CUSTOMER_SUBSCRIPTION_TRAIL_WILL_END = 'stripe.customer.subscription.trial_will_end'; const INVOICE_CREATED = 'stripe.invoice.created'; + const INVOICE_DELETED = 'stripe.invoice.deleted'; const INVOICE_FINALIZED = 'stripe.invoice.finalized'; const INVOICE_PAYMENT_FAILED = 'stripe.invoice.payment_failed'; const INVOICE_PAYMENT_SUCCEEDED = 'stripe.invoice.payment_succeeded'; From 7b1d30dc713ea2035ebe56332745fc4708f433b4 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Sun, 29 Sep 2019 20:07:49 +0100 Subject: [PATCH 20/61] Add Products and Subscription Items to the StripeClient --- Transformer/AnnotationTransformer.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Transformer/AnnotationTransformer.php b/Transformer/AnnotationTransformer.php index 08f8a4c..074e289 100644 --- a/Transformer/AnnotationTransformer.php +++ b/Transformer/AnnotationTransformer.php @@ -50,10 +50,10 @@ public function transform( $value->object == StripeObjectType::COLLECTION ) { $value = array_map(function(StripeObject $obj) { - return $obj->__toArray(true); + return $obj->toArray(true); }, $value->data); } else { - $value = $value->__toArray(true); + $value = $value->toArray(true); } } } From c481ce8dda4586f7e4d21e693a5be69afd6d9da5 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Sun, 17 Nov 2019 22:30:56 +0000 Subject: [PATCH 21/61] Updated for billing --- Controller/WebhookController.php | 40 +-- DependencyInjection/Configuration.php | 2 + Event/StripeEvent.php | 9 +- EventListener/StripeEventSubscriber.php | 10 +- Manager/Doctrine/DoctrineORMModelManager.php | 15 +- Model/AbstractCouponModel.php | 31 ++ Model/AbstractCustomerModel.php | 2 +- Model/AbstractInvoiceModel.php | 89 ++++++ Model/AbstractTaxIdModel.php | 212 +++++++++++++ Model/AbstractTaxRateModel.php | 290 ++++++++++++++++++ .../model/AbstractCouponModel.orm.xml | 1 + .../model/AbstractInvoiceModel.orm.xml | 3 + .../doctrine/model/AbstractTaxIdModel.orm.xml | 17 + .../model/AbstractTaxRateModel.orm.xml | 19 ++ 14 files changed, 711 insertions(+), 29 deletions(-) create mode 100644 Model/AbstractTaxIdModel.php create mode 100644 Model/AbstractTaxRateModel.php create mode 100644 Resources/config/doctrine/model/AbstractTaxIdModel.orm.xml create mode 100644 Resources/config/doctrine/model/AbstractTaxRateModel.orm.xml diff --git a/Controller/WebhookController.php b/Controller/WebhookController.php index 4b717ce..e737392 100644 --- a/Controller/WebhookController.php +++ b/Controller/WebhookController.php @@ -6,6 +6,7 @@ use Miracode\StripeBundle\Stripe\StripeObjectType; use Miracode\StripeBundle\StripeException; use Stripe\Error\SignatureVerification; +use Stripe\Exception\SignatureVerificationException; use Stripe\Webhook; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Request; @@ -40,24 +41,27 @@ public function handleAction(Request $request) // Secure webhook with event signature: https://stripe.com/docs/webhooks/signatures $webhookSecret = $this->getParameter('miracode_stripe.webhook_secret'); -// if($webhookSecret !== null) { -// $sigHeader = $request->headers->get('Stripe-Signature'); -// try { -// $event = Webhook::constructEvent( -// $request->getContent(), $sigHeader, $webhookSecret -// ); -// } catch(\UnexpectedValueException $e) { -// // Invalid payload -// throw new StripeException( -// sprintf('Invalid event payload', $requestData->id) -// ); -// } catch(SignatureVerification $e) { -// // Invalid signature -// throw new StripeException( -// sprintf('Invalid event signature', $requestData->id) -// ); -// } -// } + + $verifySignature = $this->getParameter('verify_stripe_signature'); + + if($verifySignature === true && $webhookSecret !== null) { + $sigHeader = $request->headers->get('Stripe-Signature'); + try { + $event = Webhook::constructEvent( + $request->getContent(), $sigHeader, $webhookSecret + ); + } catch(\UnexpectedValueException $e) { + // Invalid payload + throw new StripeException( + sprintf('Invalid event payload', $requestData->id) + ); + } catch(SignatureVerificationException $e) { + // Invalid signature + throw new StripeException( + sprintf('Invalid event signature', $requestData->id) + ); + } + } $stripeEventApi = new StripeEventApi(); diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 4bc4716..60ec9ea 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -51,6 +51,7 @@ public function getConfigTreeBuilder() ->scalarNode('charge')->cannotBeEmpty()->end() ->scalarNode('coupon')->cannotBeEmpty()->end() ->scalarNode('customer')->cannotBeEmpty()->end() + ->scalarNode('tax_id')->cannotBeEmpty()->end() ->scalarNode('discount')->cannotBeEmpty()->end() ->scalarNode('invoice')->cannotBeEmpty()->end() ->scalarNode('product')->cannotBeEmpty()->end() @@ -58,6 +59,7 @@ public function getConfigTreeBuilder() ->scalarNode('refund')->cannotBeEmpty()->end() ->scalarNode('subscription')->cannotBeEmpty()->end() ->scalarNode('subscription_item')->cannotBeEmpty()->end() + ->scalarNode('tax_rate')->cannotBeEmpty()->end() ->end() ->end() ->end() diff --git a/Event/StripeEvent.php b/Event/StripeEvent.php index 4b6d8b0..809a4b3 100644 --- a/Event/StripeEvent.php +++ b/Event/StripeEvent.php @@ -29,10 +29,14 @@ class StripeEvent extends Event const CUSTOMER_SUBSCRIPTION_CREATED = 'stripe.customer.subscription.created'; const CUSTOMER_SUBSCRIPTION_DELETED = 'stripe.customer.subscription.deleted'; const CUSTOMER_SUBSCRIPTION_UPDATED = 'stripe.customer.subscription.updated'; - const CUSTOMER_SUBSCRIPTION_TRAIL_WILL_END = 'stripe.customer.subscription.trial_will_end'; + const CUSTOMER_SUBSCRIPTION_TRIAL_WILL_END = 'stripe.customer.subscription.trial_will_end'; + const CUSTOMER_TAX_ID_CREATED = 'stripe.customer.tax_id.created'; + const CUSTOMER_TAX_ID_UPDATED = 'stripe.customer.tax_id.updated'; const INVOICE_CREATED = 'stripe.invoice.created'; const INVOICE_DELETED = 'stripe.invoice.deleted'; const INVOICE_FINALIZED = 'stripe.invoice.finalized'; + const INVOICE_ITEM_UPDATED = 'stripe.invoiceitem.updated'; + const INVOICE_PAYMENT_ACTION_REQUIRED = 'stripe.invoice.payment_action_required'; const INVOICE_PAYMENT_FAILED = 'stripe.invoice.payment_failed'; const INVOICE_PAYMENT_SUCCEEDED = 'stripe.invoice.payment_succeeded'; const INVOICE_SENT = 'stripe.invoice.sent'; @@ -41,9 +45,12 @@ class StripeEvent extends Event const PLAN_CREATED = 'stripe.plan.created'; const PLAN_DELETED = 'stripe.plan.deleted'; const PLAN_UPDATED = 'stripe.plan.updated'; + const PAYMENT_INTENT_SUCCEEDED = 'stripe.payment_intent.succeeded'; const SOURCE_CANCELED = 'stripe.source.canceled'; const SOURCE_CHARGEABLE = 'stripe.source.chargeable'; const SOURCE_FAILED = 'stripe.source.failed'; + const TAX_RATE_CREATED = 'stripe.tax_rate.created'; + const TAX_RATE_UPDATED = 'stripe.tax_rate.updated'; /** * @var StripeObject diff --git a/EventListener/StripeEventSubscriber.php b/EventListener/StripeEventSubscriber.php index 592bed3..9c3abcf 100644 --- a/EventListener/StripeEventSubscriber.php +++ b/EventListener/StripeEventSubscriber.php @@ -35,16 +35,18 @@ public static function getSubscribedEvents() StripeEvent::CHARGE_REFUNDED => 'onStripeChargeEvent', StripeEvent::CHARGE_SUCCEEDED => 'onStripeChargeEvent', StripeEvent::CHARGE_UPDATED => 'onStripeChargeEvent', - StripeEvent::COUPON_CREATED => 'onStripeEvent', StripeEvent::COUPON_UPDATED => 'onStripeEvent', StripeEvent::CUSTOMER_CREATED => 'onStripeEvent', StripeEvent::CUSTOMER_UPDATED => 'onStripeEvent', + StripeEvent::CUSTOMER_TAX_ID_CREATED => 'onStripeEvent', + StripeEvent::CUSTOMER_TAX_ID_UPDATED => 'onStripeEvent', StripeEvent::CUSTOMER_SOURCE_CREATED => 'onStripeEvent', StripeEvent::CUSTOMER_SOURCE_UPDATED => 'onStripeEvent', StripeEvent::CUSTOMER_SUBSCRIPTION_CREATED => 'onStripeEvent', StripeEvent::CUSTOMER_SUBSCRIPTION_UPDATED => 'onStripeEvent', - StripeEvent::CUSTOMER_SUBSCRIPTION_TRAIL_WILL_END => 'onStripeEvent', + StripeEvent::CUSTOMER_SUBSCRIPTION_DELETED => 'onStripeEvent', + StripeEvent::CUSTOMER_SUBSCRIPTION_TRIAL_WILL_END => 'onStripeEvent', StripeEvent::INVOICE_CREATED => 'onStripeEvent', StripeEvent::INVOICE_FINALIZED => 'onStripeEvent', StripeEvent::INVOICE_PAYMENT_FAILED => 'onStripeEvent', @@ -56,9 +58,10 @@ public static function getSubscribedEvents() StripeEvent::SOURCE_CANCELED => 'onStripeEvent', StripeEvent::SOURCE_CHARGEABLE => 'onStripeEvent', StripeEvent::SOURCE_FAILED => 'onStripeEvent', - StripeEvent::CUSTOMER_SUBSCRIPTION_DELETED => 'onStripeEvent', StripeEvent::COUPON_DELETED => 'onStripeDeleteEvent', + StripeEvent::TAX_RATE_CREATED => 'onStripeEvent', + StripeEvent::TAX_RATE_UPDATED => 'onStripeEvent', StripeEvent::CUSTOMER_DELETED => 'onStripeDeleteEvent', StripeEvent::CUSTOMER_SOURCE_DELETED => 'onStripeDeleteEvent', StripeEvent::PLAN_DELETED => 'onStripeDeleteEvent', @@ -77,6 +80,7 @@ public function onStripeEvent(StripeEvent $event) } } + /** * @param StripeEvent $event */ diff --git a/Manager/Doctrine/DoctrineORMModelManager.php b/Manager/Doctrine/DoctrineORMModelManager.php index 51dae97..3176420 100644 --- a/Manager/Doctrine/DoctrineORMModelManager.php +++ b/Manager/Doctrine/DoctrineORMModelManager.php @@ -10,6 +10,7 @@ use Miracode\StripeBundle\Model\StripeModelInterface; use Miracode\StripeBundle\StripeException; use Miracode\StripeBundle\Transformer\TransformerInterface; +use Stripe\Customer; use Stripe\StripeObject; class DoctrineORMModelManager implements ModelManagerInterface @@ -212,14 +213,16 @@ protected function createModel(StripeObject $object) } // // If the object has a customer then map. -// if($object->customer){ -// $class->setCustomer($this->objectManager->find(AbstractCustomerModel::class, $object->customer)); -// } + if($object->customer){ + // Get local customer; + $customer = $this->objectManager->find($this->modelClasses['customer'], $object->customer); + $class->setCustomer($customer); + } // // // If the object has a has a product then map. -// if($object->product){ -// $class->setCustomer($this->objectManager->find(AbstractProductModel::class, $object->product)); -// } + if($object->product){ + $class->setCustomer($this->objectManager->find($this->modelClasses['product'], $object->product)); + } return $class; diff --git a/Model/AbstractCouponModel.php b/Model/AbstractCouponModel.php index 7855fa8..54ba696 100644 --- a/Model/AbstractCouponModel.php +++ b/Model/AbstractCouponModel.php @@ -20,6 +20,13 @@ abstract class AbstractCouponModel extends StripeModel */ protected $created; + /** + * @StripeObjectParam + * + * @var string + */ + protected $name; + /** * @StripeObjectParam * @@ -329,4 +336,28 @@ public function setValid($valid) return $this; } + + /** + * @return string|null + */ + public function getName(): ?string + { + return $this->name; + } + + /** + * Set Name. + * + * @param string $name + * + * @return AbstractCouponModel + */ + public function setName(string $name): AbstractCouponModel + { + $this->name = $name; + + return $this; + } + + } diff --git a/Model/AbstractCustomerModel.php b/Model/AbstractCustomerModel.php index e91f608..3971215 100644 --- a/Model/AbstractCustomerModel.php +++ b/Model/AbstractCustomerModel.php @@ -36,7 +36,7 @@ abstract class AbstractCustomerModel extends StripeModel /** * @StripeObjectParam(name="default_source") - * + * @deprecated * @var string */ protected $defaultSource; diff --git a/Model/AbstractInvoiceModel.php b/Model/AbstractInvoiceModel.php index 6b27fa1..5f0ce17 100644 --- a/Model/AbstractInvoiceModel.php +++ b/Model/AbstractInvoiceModel.php @@ -209,6 +209,13 @@ abstract class AbstractInvoiceModel extends StripeModel */ protected $subtotal; + /** + * @StripeObjectParam + * + * @var array|null + */ + protected $discount; + /** * @StripeObjectParam * @@ -237,6 +244,20 @@ abstract class AbstractInvoiceModel extends StripeModel */ protected $webhooksDeliveredAt; + /** + * @StripeObjectParam(name="hosted_invoice_url") + * + * @var string + */ + protected $hostedInvoiceUrl; + + /** + * @StripeObjectParam(name="invoice_pdf") + * + * @var string + */ + protected $invoicePdf; + /** * @return int */ @@ -896,4 +917,72 @@ public function setWebhooksDeliveredAt($webhooksDeliveredAt) return $this; } + + /** + * @return string + */ + public function getHostedInvoiceUrl(): string + { + return $this->hostedInvoiceUrl; + } + + /** + * Set HostedInvoiceUrl. + * + * @param string $hostedInvoiceUrl + * + * @return AbstractInvoiceModel + */ + public function setHostedInvoiceUrl(string $hostedInvoiceUrl): AbstractInvoiceModel + { + $this->hostedInvoiceUrl = $hostedInvoiceUrl; + + return $this; + } + + /** + * @return string + */ + public function getInvoicePdf(): string + { + return $this->invoicePdf; + } + + /** + * Set InvoicePdf. + * + * @param string $invoicePdf + * + * @return AbstractInvoiceModel + */ + public function setInvoicePdf(string $invoicePdf): AbstractInvoiceModel + { + $this->invoicePdf = $invoicePdf; + + return $this; + } + + /** + * @return array|null + */ + public function getDiscount(): ?array + { + return $this->discount; + } + + /** + * Set Discount. + * + * @param array|null $discount + * + * @return AbstractInvoiceModel + */ + public function setDiscount(?array $discount): AbstractInvoiceModel + { + $this->discount = $discount; + + return $this; + } + + } \ No newline at end of file diff --git a/Model/AbstractTaxIdModel.php b/Model/AbstractTaxIdModel.php new file mode 100644 index 0000000..1b472a3 --- /dev/null +++ b/Model/AbstractTaxIdModel.php @@ -0,0 +1,212 @@ +country; + } + + /** + * Set Country. + * + * @param string $country + * + * @return AbstractTaxIdModel + */ + public function setCountry(string $country): AbstractTaxIdModel + { + $this->country = $country; + + return $this; + } + + /** + * @return int + */ + public function getCreated(): int + { + return $this->created; + } + + /** + * Set Created. + * + * @param int $created + * + * @return AbstractTaxIdModel + */ + public function setCreated(int $created): AbstractTaxIdModel + { + $this->created = $created; + + return $this; + } + + /** + * @return string + */ + public function getCustomer() + { + return $this->customer; + } + + /** + * Set Customer. + * + * @param string $customer + * + * @return AbstractTaxIdModel + */ + public function setCustomer( $customer) + { + $this->customer = $customer; + + return $this; + } + + /** + * @return bool + */ + public function isLivemode(): bool + { + return $this->livemode; + } + + /** + * Set Livemode. + * + * @param bool $livemode + * + * @return AbstractTaxIdModel + */ + public function setLivemode(bool $livemode): AbstractTaxIdModel + { + $this->livemode = $livemode; + + return $this; + } + + /** + * @return string + */ + public function getType(): string + { + return $this->type; + } + + /** + * Set Type. + * + * @param string $type + * + * @return AbstractTaxIdModel + */ + public function setType(string $type): AbstractTaxIdModel + { + $this->type = $type; + + return $this; + } + + /** + * @return string + */ + public function getValue(): string + { + return $this->value; + } + + /** + * Set Value. + * + * @param string $value + * + * @return AbstractTaxIdModel + */ + public function setValue(string $value): AbstractTaxIdModel + { + $this->value = $value; + + return $this; + } + + /** + * @return array + */ + public function getVerification(): array + { + return $this->verification; + } + + /** + * Set Verification. + * + * @param array $verification + * + * @return AbstractTaxIdModel + */ + public function setVerification(array $verification): AbstractTaxIdModel + { + $this->verification = $verification; + + return $this; + } + +} diff --git a/Model/AbstractTaxRateModel.php b/Model/AbstractTaxRateModel.php new file mode 100644 index 0000000..c65652e --- /dev/null +++ b/Model/AbstractTaxRateModel.php @@ -0,0 +1,290 @@ +created; + } + + /** + * @param int $created + * + * @return $this + */ + public function setCreated($created) + { + $this->created = $created; + + return $this; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } + + /** + * @param string $description + * + * @return $this + */ + public function setDescription($description) + { + $this->description = $description; + + return $this; + } + + /** + * @return bool + */ + public function isLivemode() + { + return $this->livemode; + } + + /** + * @param bool $livemode + * + * @return $this + */ + public function setLivemode($livemode) + { + $this->livemode = $livemode; + + return $this; + } + + /** + * @return array + */ + public function getMetadata() + { + return $this->metadata; + } + + /** + * @param array $metadata + * + * @return $this + */ + public function setMetadata($metadata) + { + $this->metadata = $metadata; + + return $this; + } + + /** + * @return string + */ + public function getSource() + { + return $this->source; + } + + /** + * @param string $source + * + * @return $this + */ + public function setSource($source) + { + $this->source = $source; + + return $this; + } + + /** + * @return bool + */ + public function isActive(): bool + { + return $this->active; + } + + /** + * Set Active. + * + * @param bool $active + * + * @return AbstractTaxRateModel + */ + public function setActive(bool $active): AbstractTaxRateModel + { + $this->active = $active; + + return $this; + } + + /** + * @return string + */ + public function getDisplayName(): string + { + return $this->displayName; + } + + /** + * Set DisplayName. + * + * @param string $displayName + * + * @return AbstractTaxRateModel + */ + public function setDisplayName(string $displayName): AbstractTaxRateModel + { + $this->displayName = $displayName; + + return $this; + } + + /** + * @return bool + */ + public function isInclusive(): bool + { + return $this->inclusive; + } + + /** + * Set Inclusive. + * + * @param bool $inclusive + * + * @return AbstractTaxRateModel + */ + public function setInclusive(bool $inclusive): AbstractTaxRateModel + { + $this->inclusive = $inclusive; + + return $this; + } + + /** + * @return string + */ + public function getJurisdiction(): string + { + return $this->jurisdiction; + } + + /** + * Set Jurisdiction. + * + * @param string $jurisdiction + * + * @return AbstractTaxRateModel + */ + public function setJurisdiction(string $jurisdiction): AbstractTaxRateModel + { + $this->jurisdiction = $jurisdiction; + + return $this; + } + + /** + * @return int + */ + public function getPercentage(): int + { + return $this->percentage; + } + + /** + * Set Percentage. + * + * @param int $percentage + * + * @return AbstractTaxRateModel + */ + public function setPercentage(int $percentage): AbstractTaxRateModel + { + $this->percentage = $percentage; + + return $this; + } + +} diff --git a/Resources/config/doctrine/model/AbstractCouponModel.orm.xml b/Resources/config/doctrine/model/AbstractCouponModel.orm.xml index 91255b4..a860af9 100644 --- a/Resources/config/doctrine/model/AbstractCouponModel.orm.xml +++ b/Resources/config/doctrine/model/AbstractCouponModel.orm.xml @@ -6,6 +6,7 @@ + diff --git a/Resources/config/doctrine/model/AbstractInvoiceModel.orm.xml b/Resources/config/doctrine/model/AbstractInvoiceModel.orm.xml index ccbe503..a0b5664 100644 --- a/Resources/config/doctrine/model/AbstractInvoiceModel.orm.xml +++ b/Resources/config/doctrine/model/AbstractInvoiceModel.orm.xml @@ -33,10 +33,13 @@ + + + diff --git a/Resources/config/doctrine/model/AbstractTaxIdModel.orm.xml b/Resources/config/doctrine/model/AbstractTaxIdModel.orm.xml new file mode 100644 index 0000000..3ce0e97 --- /dev/null +++ b/Resources/config/doctrine/model/AbstractTaxIdModel.orm.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + diff --git a/Resources/config/doctrine/model/AbstractTaxRateModel.orm.xml b/Resources/config/doctrine/model/AbstractTaxRateModel.orm.xml new file mode 100644 index 0000000..89bfcbe --- /dev/null +++ b/Resources/config/doctrine/model/AbstractTaxRateModel.orm.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + From 234dbd0582466c79f3750cca0028d582fb0d23ef Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Fri, 22 Nov 2019 01:16:32 +0000 Subject: [PATCH 22/61] Updated for billing --- Controller/WebhookController.php | 1 + Manager/Doctrine/DoctrineORMModelManager.php | 12 ------------ 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/Controller/WebhookController.php b/Controller/WebhookController.php index e737392..5c53a69 100644 --- a/Controller/WebhookController.php +++ b/Controller/WebhookController.php @@ -26,6 +26,7 @@ public function handleAction(Request $request) { $requestData = json_decode($request->getContent()); + if (!isset($requestData->id) || !isset($requestData->object)) { throw new BadRequestHttpException('Invalid webhook request data'); } diff --git a/Manager/Doctrine/DoctrineORMModelManager.php b/Manager/Doctrine/DoctrineORMModelManager.php index 3176420..a8ac75c 100644 --- a/Manager/Doctrine/DoctrineORMModelManager.php +++ b/Manager/Doctrine/DoctrineORMModelManager.php @@ -212,18 +212,6 @@ protected function createModel(StripeObject $object) $class->setId($object->id); } -// // If the object has a customer then map. - if($object->customer){ - // Get local customer; - $customer = $this->objectManager->find($this->modelClasses['customer'], $object->customer); - $class->setCustomer($customer); - } -// -// // If the object has a has a product then map. - if($object->product){ - $class->setCustomer($this->objectManager->find($this->modelClasses['product'], $object->product)); - } - return $class; } From 8a95e82728ede1743272c9135961e523260f8e31 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Wed, 27 Nov 2019 11:59:19 +0000 Subject: [PATCH 23/61] Add invoice.voided event --- Event/StripeEvent.php | 1 + 1 file changed, 1 insertion(+) diff --git a/Event/StripeEvent.php b/Event/StripeEvent.php index 809a4b3..a4c2fe8 100644 --- a/Event/StripeEvent.php +++ b/Event/StripeEvent.php @@ -42,6 +42,7 @@ class StripeEvent extends Event const INVOICE_SENT = 'stripe.invoice.sent'; const INVOICE_UPCOMING = 'stripe.invoice.upcoming'; const INVOICE_UPDATED = 'stripe.invoice.updated'; + const INVOICE_VOIDED = 'stripe.invoice.voided'; const PLAN_CREATED = 'stripe.plan.created'; const PLAN_DELETED = 'stripe.plan.deleted'; const PLAN_UPDATED = 'stripe.plan.updated'; From 4cd5eb676b95dc1710d2b6e1ff141c54d74ba44b Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Wed, 27 Nov 2019 20:11:39 +0000 Subject: [PATCH 24/61] Add invoice.voided event --- Model/AbstractInvoiceModel.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Model/AbstractInvoiceModel.php b/Model/AbstractInvoiceModel.php index 5f0ce17..93d1770 100644 --- a/Model/AbstractInvoiceModel.php +++ b/Model/AbstractInvoiceModel.php @@ -247,7 +247,7 @@ abstract class AbstractInvoiceModel extends StripeModel /** * @StripeObjectParam(name="hosted_invoice_url") * - * @var string + * @var string|null */ protected $hostedInvoiceUrl; @@ -919,9 +919,9 @@ public function setWebhooksDeliveredAt($webhooksDeliveredAt) } /** - * @return string + * @return string|null */ - public function getHostedInvoiceUrl(): string + public function getHostedInvoiceUrl() { return $this->hostedInvoiceUrl; } @@ -929,11 +929,11 @@ public function getHostedInvoiceUrl(): string /** * Set HostedInvoiceUrl. * - * @param string $hostedInvoiceUrl + * @param string|uull $hostedInvoiceUrl * * @return AbstractInvoiceModel */ - public function setHostedInvoiceUrl(string $hostedInvoiceUrl): AbstractInvoiceModel + public function setHostedInvoiceUrl($hostedInvoiceUrl): AbstractInvoiceModel { $this->hostedInvoiceUrl = $hostedInvoiceUrl; From 81569eff342d02d0bcde17fe1fb0743bebb3510f Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Wed, 27 Nov 2019 20:19:13 +0000 Subject: [PATCH 25/61] Add invoice.voided event --- Model/AbstractInvoiceModel.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Model/AbstractInvoiceModel.php b/Model/AbstractInvoiceModel.php index 93d1770..ffb5436 100644 --- a/Model/AbstractInvoiceModel.php +++ b/Model/AbstractInvoiceModel.php @@ -254,7 +254,7 @@ abstract class AbstractInvoiceModel extends StripeModel /** * @StripeObjectParam(name="invoice_pdf") * - * @var string + * @var string|null */ protected $invoicePdf; @@ -941,9 +941,9 @@ public function setHostedInvoiceUrl($hostedInvoiceUrl): AbstractInvoiceModel } /** - * @return string + * @return string|null */ - public function getInvoicePdf(): string + public function getInvoicePdf() { return $this->invoicePdf; } @@ -951,11 +951,11 @@ public function getInvoicePdf(): string /** * Set InvoicePdf. * - * @param string $invoicePdf + * @param string|null $invoicePdf * * @return AbstractInvoiceModel */ - public function setInvoicePdf(string $invoicePdf): AbstractInvoiceModel + public function setInvoicePdf($invoicePdf): AbstractInvoiceModel { $this->invoicePdf = $invoicePdf; From af74432c187649f392027f53de1ea928d27fdcab Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Mon, 2 Dec 2019 22:01:49 +0000 Subject: [PATCH 26/61] Add invoice.voided event --- Model/AbstractInvoiceModel.php | 28 +++++++++++++++++++ .../model/AbstractInvoiceModel.orm.xml | 1 + 2 files changed, 29 insertions(+) diff --git a/Model/AbstractInvoiceModel.php b/Model/AbstractInvoiceModel.php index ffb5436..a895508 100644 --- a/Model/AbstractInvoiceModel.php +++ b/Model/AbstractInvoiceModel.php @@ -6,6 +6,14 @@ abstract class AbstractInvoiceModel extends StripeModel { + + /** + * @StripeObjectParam(name="amount_paid") + * + * @var int + */ + protected $amountPaid; + /** * @StripeObjectParam(name="amount_due") * @@ -258,6 +266,26 @@ abstract class AbstractInvoiceModel extends StripeModel */ protected $invoicePdf; + /** + * @return int + */ + public function getAmountPaid() + { + return $this->amountPaid; + } + + /** + * @param int $amountPaid + * + * @return $this + */ + public function setAmountPaid($amountPaid) + { + $this->amountPaid = $amountPaid; + + return $this; + } + /** * @return int */ diff --git a/Resources/config/doctrine/model/AbstractInvoiceModel.orm.xml b/Resources/config/doctrine/model/AbstractInvoiceModel.orm.xml index a0b5664..db7725a 100644 --- a/Resources/config/doctrine/model/AbstractInvoiceModel.orm.xml +++ b/Resources/config/doctrine/model/AbstractInvoiceModel.orm.xml @@ -5,6 +5,7 @@ + From 58399f376b8856db5bed0cf3ac75bb2cb5c22cf2 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Sat, 23 May 2020 13:03:18 +0100 Subject: [PATCH 27/61] Update for Symfoy 5 --- DependencyInjection/Configuration.php | 10 ++++++++-- Event/StripeEvent.php | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 60ec9ea..03fc702 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -17,8 +17,14 @@ class Configuration implements ConfigurationInterface */ public function getConfigTreeBuilder() { - $treeBuilder = new TreeBuilder(); - $rootNode = $treeBuilder->root('miracode_stripe'); + $treeBuilder = new TreeBuilder('miracode_stripe'); + + if (method_exists($treeBuilder, 'getRootNode')) { + $rootNode = $treeBuilder->getRootNode(); + } else { + // for symfony/config 4.1 and older + $rootNode = $treeBuilder->root('miracode_stripe'); + } $supportedDrivers = array('orm', /** coming soon) */); diff --git a/Event/StripeEvent.php b/Event/StripeEvent.php index a4c2fe8..022cb07 100644 --- a/Event/StripeEvent.php +++ b/Event/StripeEvent.php @@ -4,7 +4,7 @@ use Miracode\StripeBundle\StripeException; use Stripe\StripeObject; -use Symfony\Component\EventDispatcher\Event; +use Symfony\Contracts\EventDispatcher\Event; class StripeEvent extends Event { From 8db559ebcc586642046499cf32526795d38b77cd Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Thu, 18 Jun 2020 01:24:12 +0100 Subject: [PATCH 28/61] Update for Symfoy 5 --- .gitignore | 0 .travis.yml | 0 Annotation/StripeObjectParam.php | 0 Controller/WebhookController.php | 0 DependencyInjection/Compiler/RegisterDoctrineMappingPass.php | 0 DependencyInjection/Configuration.php | 0 DependencyInjection/MiracodeStripeExtension.php | 0 Event/StripeEvent.php | 0 EventListener/StripeEventSubscriber.php | 0 LICENSE | 0 Manager/Doctrine/DoctrineORMModelManager.php | 0 Manager/ModelManagerInterface.php | 0 MiracodeStripeBundle.php | 0 Model/AbstractCardModel.php | 0 Model/AbstractChargeModel.php | 0 Model/AbstractCouponModel.php | 0 Model/AbstractCustomerModel.php | 0 Model/AbstractInvoiceModel.php | 0 Model/AbstractPlanModel.php | 0 Model/AbstractProductModel.php | 0 Model/AbstractRefundModel.php | 0 Model/AbstractSubscriptionModel.php | 0 Model/AbstractTaxIdModel.php | 0 Model/AbstractTaxRateModel.php | 0 Model/SafeDeleteModelInterface.php | 0 Model/StripeModel.php | 0 Model/StripeModelInterface.php | 0 Model/StripeUserInterface.php | 0 Model/Traits/SafeDeleteTrait.php | 0 README.md | 0 Resources/config/doctrine/model/AbstractCardModel.orm.xml | 0 Resources/config/doctrine/model/AbstractChargeModel.orm.xml | 0 Resources/config/doctrine/model/AbstractCouponModel.orm.xml | 0 Resources/config/doctrine/model/AbstractCustomerModel.orm.xml | 0 Resources/config/doctrine/model/AbstractInvoiceModel.orm.xml | 0 Resources/config/doctrine/model/AbstractPlanModel.orm.xml | 0 Resources/config/doctrine/model/AbstractProductModel.orm.xml | 0 Resources/config/doctrine/model/AbstractRefundModel.orm.xml | 0 Resources/config/doctrine/model/AbstractSubscriptionModel.orm.xml | 0 Resources/config/doctrine/model/AbstractTaxIdModel.orm.xml | 0 Resources/config/doctrine/model/AbstractTaxRateModel.orm.xml | 0 Resources/config/listener.xml | 0 Resources/config/routing.xml | 0 Resources/config/services.xml | 0 Stripe/StripeClient.php | 0 Stripe/StripeObjectType.php | 0 StripeException.php | 0 Tests/DependencyInjection/MiracodeStripeExtensionTest.php | 0 Tests/Event/StripeEventTest.php | 0 Tests/Mock/CustomEntityManagerMock.php | 0 Tests/Mock/EntityManagerMock.php | 0 Tests/Mock/TransformerMock.php | 0 Tests/TestModel/TestCustomer.php | 0 Tests/bootstrap.php | 0 Transformer/AnnotationTransformer.php | 0 Transformer/TransformerInterface.php | 0 composer.json | 0 phpunit.xml.dist | 0 58 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 .gitignore mode change 100644 => 100755 .travis.yml mode change 100644 => 100755 Annotation/StripeObjectParam.php mode change 100644 => 100755 Controller/WebhookController.php mode change 100644 => 100755 DependencyInjection/Compiler/RegisterDoctrineMappingPass.php mode change 100644 => 100755 DependencyInjection/Configuration.php mode change 100644 => 100755 DependencyInjection/MiracodeStripeExtension.php mode change 100644 => 100755 Event/StripeEvent.php mode change 100644 => 100755 EventListener/StripeEventSubscriber.php mode change 100644 => 100755 LICENSE mode change 100644 => 100755 Manager/Doctrine/DoctrineORMModelManager.php mode change 100644 => 100755 Manager/ModelManagerInterface.php mode change 100644 => 100755 MiracodeStripeBundle.php mode change 100644 => 100755 Model/AbstractCardModel.php mode change 100644 => 100755 Model/AbstractChargeModel.php mode change 100644 => 100755 Model/AbstractCouponModel.php mode change 100644 => 100755 Model/AbstractCustomerModel.php mode change 100644 => 100755 Model/AbstractInvoiceModel.php mode change 100644 => 100755 Model/AbstractPlanModel.php mode change 100644 => 100755 Model/AbstractProductModel.php mode change 100644 => 100755 Model/AbstractRefundModel.php mode change 100644 => 100755 Model/AbstractSubscriptionModel.php mode change 100644 => 100755 Model/AbstractTaxIdModel.php mode change 100644 => 100755 Model/AbstractTaxRateModel.php mode change 100644 => 100755 Model/SafeDeleteModelInterface.php mode change 100644 => 100755 Model/StripeModel.php mode change 100644 => 100755 Model/StripeModelInterface.php mode change 100644 => 100755 Model/StripeUserInterface.php mode change 100644 => 100755 Model/Traits/SafeDeleteTrait.php mode change 100644 => 100755 README.md mode change 100644 => 100755 Resources/config/doctrine/model/AbstractCardModel.orm.xml mode change 100644 => 100755 Resources/config/doctrine/model/AbstractChargeModel.orm.xml mode change 100644 => 100755 Resources/config/doctrine/model/AbstractCouponModel.orm.xml mode change 100644 => 100755 Resources/config/doctrine/model/AbstractCustomerModel.orm.xml mode change 100644 => 100755 Resources/config/doctrine/model/AbstractInvoiceModel.orm.xml mode change 100644 => 100755 Resources/config/doctrine/model/AbstractPlanModel.orm.xml mode change 100644 => 100755 Resources/config/doctrine/model/AbstractProductModel.orm.xml mode change 100644 => 100755 Resources/config/doctrine/model/AbstractRefundModel.orm.xml mode change 100644 => 100755 Resources/config/doctrine/model/AbstractSubscriptionModel.orm.xml mode change 100644 => 100755 Resources/config/doctrine/model/AbstractTaxIdModel.orm.xml mode change 100644 => 100755 Resources/config/doctrine/model/AbstractTaxRateModel.orm.xml mode change 100644 => 100755 Resources/config/listener.xml mode change 100644 => 100755 Resources/config/routing.xml mode change 100644 => 100755 Resources/config/services.xml mode change 100644 => 100755 Stripe/StripeClient.php mode change 100644 => 100755 Stripe/StripeObjectType.php mode change 100644 => 100755 StripeException.php mode change 100644 => 100755 Tests/DependencyInjection/MiracodeStripeExtensionTest.php mode change 100644 => 100755 Tests/Event/StripeEventTest.php mode change 100644 => 100755 Tests/Mock/CustomEntityManagerMock.php mode change 100644 => 100755 Tests/Mock/EntityManagerMock.php mode change 100644 => 100755 Tests/Mock/TransformerMock.php mode change 100644 => 100755 Tests/TestModel/TestCustomer.php mode change 100644 => 100755 Tests/bootstrap.php mode change 100644 => 100755 Transformer/AnnotationTransformer.php mode change 100644 => 100755 Transformer/TransformerInterface.php mode change 100644 => 100755 composer.json mode change 100644 => 100755 phpunit.xml.dist diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/.travis.yml b/.travis.yml old mode 100644 new mode 100755 diff --git a/Annotation/StripeObjectParam.php b/Annotation/StripeObjectParam.php old mode 100644 new mode 100755 diff --git a/Controller/WebhookController.php b/Controller/WebhookController.php old mode 100644 new mode 100755 diff --git a/DependencyInjection/Compiler/RegisterDoctrineMappingPass.php b/DependencyInjection/Compiler/RegisterDoctrineMappingPass.php old mode 100644 new mode 100755 diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php old mode 100644 new mode 100755 diff --git a/DependencyInjection/MiracodeStripeExtension.php b/DependencyInjection/MiracodeStripeExtension.php old mode 100644 new mode 100755 diff --git a/Event/StripeEvent.php b/Event/StripeEvent.php old mode 100644 new mode 100755 diff --git a/EventListener/StripeEventSubscriber.php b/EventListener/StripeEventSubscriber.php old mode 100644 new mode 100755 diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/Manager/Doctrine/DoctrineORMModelManager.php b/Manager/Doctrine/DoctrineORMModelManager.php old mode 100644 new mode 100755 diff --git a/Manager/ModelManagerInterface.php b/Manager/ModelManagerInterface.php old mode 100644 new mode 100755 diff --git a/MiracodeStripeBundle.php b/MiracodeStripeBundle.php old mode 100644 new mode 100755 diff --git a/Model/AbstractCardModel.php b/Model/AbstractCardModel.php old mode 100644 new mode 100755 diff --git a/Model/AbstractChargeModel.php b/Model/AbstractChargeModel.php old mode 100644 new mode 100755 diff --git a/Model/AbstractCouponModel.php b/Model/AbstractCouponModel.php old mode 100644 new mode 100755 diff --git a/Model/AbstractCustomerModel.php b/Model/AbstractCustomerModel.php old mode 100644 new mode 100755 diff --git a/Model/AbstractInvoiceModel.php b/Model/AbstractInvoiceModel.php old mode 100644 new mode 100755 diff --git a/Model/AbstractPlanModel.php b/Model/AbstractPlanModel.php old mode 100644 new mode 100755 diff --git a/Model/AbstractProductModel.php b/Model/AbstractProductModel.php old mode 100644 new mode 100755 diff --git a/Model/AbstractRefundModel.php b/Model/AbstractRefundModel.php old mode 100644 new mode 100755 diff --git a/Model/AbstractSubscriptionModel.php b/Model/AbstractSubscriptionModel.php old mode 100644 new mode 100755 diff --git a/Model/AbstractTaxIdModel.php b/Model/AbstractTaxIdModel.php old mode 100644 new mode 100755 diff --git a/Model/AbstractTaxRateModel.php b/Model/AbstractTaxRateModel.php old mode 100644 new mode 100755 diff --git a/Model/SafeDeleteModelInterface.php b/Model/SafeDeleteModelInterface.php old mode 100644 new mode 100755 diff --git a/Model/StripeModel.php b/Model/StripeModel.php old mode 100644 new mode 100755 diff --git a/Model/StripeModelInterface.php b/Model/StripeModelInterface.php old mode 100644 new mode 100755 diff --git a/Model/StripeUserInterface.php b/Model/StripeUserInterface.php old mode 100644 new mode 100755 diff --git a/Model/Traits/SafeDeleteTrait.php b/Model/Traits/SafeDeleteTrait.php old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/Resources/config/doctrine/model/AbstractCardModel.orm.xml b/Resources/config/doctrine/model/AbstractCardModel.orm.xml old mode 100644 new mode 100755 diff --git a/Resources/config/doctrine/model/AbstractChargeModel.orm.xml b/Resources/config/doctrine/model/AbstractChargeModel.orm.xml old mode 100644 new mode 100755 diff --git a/Resources/config/doctrine/model/AbstractCouponModel.orm.xml b/Resources/config/doctrine/model/AbstractCouponModel.orm.xml old mode 100644 new mode 100755 diff --git a/Resources/config/doctrine/model/AbstractCustomerModel.orm.xml b/Resources/config/doctrine/model/AbstractCustomerModel.orm.xml old mode 100644 new mode 100755 diff --git a/Resources/config/doctrine/model/AbstractInvoiceModel.orm.xml b/Resources/config/doctrine/model/AbstractInvoiceModel.orm.xml old mode 100644 new mode 100755 diff --git a/Resources/config/doctrine/model/AbstractPlanModel.orm.xml b/Resources/config/doctrine/model/AbstractPlanModel.orm.xml old mode 100644 new mode 100755 diff --git a/Resources/config/doctrine/model/AbstractProductModel.orm.xml b/Resources/config/doctrine/model/AbstractProductModel.orm.xml old mode 100644 new mode 100755 diff --git a/Resources/config/doctrine/model/AbstractRefundModel.orm.xml b/Resources/config/doctrine/model/AbstractRefundModel.orm.xml old mode 100644 new mode 100755 diff --git a/Resources/config/doctrine/model/AbstractSubscriptionModel.orm.xml b/Resources/config/doctrine/model/AbstractSubscriptionModel.orm.xml old mode 100644 new mode 100755 diff --git a/Resources/config/doctrine/model/AbstractTaxIdModel.orm.xml b/Resources/config/doctrine/model/AbstractTaxIdModel.orm.xml old mode 100644 new mode 100755 diff --git a/Resources/config/doctrine/model/AbstractTaxRateModel.orm.xml b/Resources/config/doctrine/model/AbstractTaxRateModel.orm.xml old mode 100644 new mode 100755 diff --git a/Resources/config/listener.xml b/Resources/config/listener.xml old mode 100644 new mode 100755 diff --git a/Resources/config/routing.xml b/Resources/config/routing.xml old mode 100644 new mode 100755 diff --git a/Resources/config/services.xml b/Resources/config/services.xml old mode 100644 new mode 100755 diff --git a/Stripe/StripeClient.php b/Stripe/StripeClient.php old mode 100644 new mode 100755 diff --git a/Stripe/StripeObjectType.php b/Stripe/StripeObjectType.php old mode 100644 new mode 100755 diff --git a/StripeException.php b/StripeException.php old mode 100644 new mode 100755 diff --git a/Tests/DependencyInjection/MiracodeStripeExtensionTest.php b/Tests/DependencyInjection/MiracodeStripeExtensionTest.php old mode 100644 new mode 100755 diff --git a/Tests/Event/StripeEventTest.php b/Tests/Event/StripeEventTest.php old mode 100644 new mode 100755 diff --git a/Tests/Mock/CustomEntityManagerMock.php b/Tests/Mock/CustomEntityManagerMock.php old mode 100644 new mode 100755 diff --git a/Tests/Mock/EntityManagerMock.php b/Tests/Mock/EntityManagerMock.php old mode 100644 new mode 100755 diff --git a/Tests/Mock/TransformerMock.php b/Tests/Mock/TransformerMock.php old mode 100644 new mode 100755 diff --git a/Tests/TestModel/TestCustomer.php b/Tests/TestModel/TestCustomer.php old mode 100644 new mode 100755 diff --git a/Tests/bootstrap.php b/Tests/bootstrap.php old mode 100644 new mode 100755 diff --git a/Transformer/AnnotationTransformer.php b/Transformer/AnnotationTransformer.php old mode 100644 new mode 100755 diff --git a/Transformer/TransformerInterface.php b/Transformer/TransformerInterface.php old mode 100644 new mode 100755 diff --git a/composer.json b/composer.json old mode 100644 new mode 100755 diff --git a/phpunit.xml.dist b/phpunit.xml.dist old mode 100644 new mode 100755 From 60b170a07784c54f6e4d3d45aa21f52b48a7911c Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Tue, 4 Aug 2020 16:05:30 +0100 Subject: [PATCH 29/61] Update StripeClient.php Change subscription item --- Stripe/StripeClient.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Stripe/StripeClient.php b/Stripe/StripeClient.php index e692f2b..47579cd 100644 --- a/Stripe/StripeClient.php +++ b/Stripe/StripeClient.php @@ -268,7 +268,7 @@ public function createSubscriptionItem($subscriptionId, $planId, $quantity, $par $data = array_merge($parameters, $data); } - return Subscription::create($data); + return SubscriptionItem::create($data); } /** From 84edaf8cadc82d6914cd49a88e530b5ec1ed79a3 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Tue, 4 Aug 2020 16:26:05 +0100 Subject: [PATCH 30/61] Update StripeEvent.php --- Event/StripeEvent.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Event/StripeEvent.php b/Event/StripeEvent.php index 022cb07..a4c2fe8 100644 --- a/Event/StripeEvent.php +++ b/Event/StripeEvent.php @@ -4,7 +4,7 @@ use Miracode\StripeBundle\StripeException; use Stripe\StripeObject; -use Symfony\Contracts\EventDispatcher\Event; +use Symfony\Component\EventDispatcher\Event; class StripeEvent extends Event { From 8c56c70bb075f339b9692242b9a60fcf038b80c4 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Mon, 10 Aug 2020 15:50:46 +0100 Subject: [PATCH 31/61] Update for Symfoy 5 --- Event/StripeEvent.php | 2 +- EventListener/StripeEventSubscriber.php | 2 +- README.md | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Event/StripeEvent.php b/Event/StripeEvent.php index a4c2fe8..022cb07 100755 --- a/Event/StripeEvent.php +++ b/Event/StripeEvent.php @@ -4,7 +4,7 @@ use Miracode\StripeBundle\StripeException; use Stripe\StripeObject; -use Symfony\Component\EventDispatcher\Event; +use Symfony\Contracts\EventDispatcher\Event; class StripeEvent extends Event { diff --git a/EventListener/StripeEventSubscriber.php b/EventListener/StripeEventSubscriber.php index 9c3abcf..7d994a9 100755 --- a/EventListener/StripeEventSubscriber.php +++ b/EventListener/StripeEventSubscriber.php @@ -5,7 +5,7 @@ use Miracode\StripeBundle\Event\StripeEvent; use Miracode\StripeBundle\Manager\ModelManagerInterface; use Stripe\StripeObject; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Contracts\EventDispatcher\EventSubscriberInterface; class StripeEventSubscriber implements EventSubscriberInterface { diff --git a/README.md b/README.md index a386bc2..fdf3e2c 100755 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ Event Subscriber example: namespace App\EventListener; use Miracode\StripeBundle\Event\StripeEvent; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Contracts\EventDispatcher\EventSubscriberInterface; class StripeSubscriber implements EventSubscriberInterface { @@ -135,7 +135,7 @@ namespace App\EventListener; use Miracode\StripeBundle\Event\StripeEvent; use Miracode\StripeBundle\EventListener\StripeEventSubscriber as MiracodeStripeEventSubscriber -use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Contracts\EventDispatcher\EventSubscriberInterface; class StripeEventSubscriber extends MiracodeStripeEventSubscriber implements EventSubscriberInterface { From 81aad4a39f0ef546190a0831e717367d230028fd Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Mon, 10 Aug 2020 16:54:31 +0100 Subject: [PATCH 32/61] Update for Symfoy 5 --- EventListener/StripeEventSubscriber.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EventListener/StripeEventSubscriber.php b/EventListener/StripeEventSubscriber.php index 7d994a9..9c3abcf 100755 --- a/EventListener/StripeEventSubscriber.php +++ b/EventListener/StripeEventSubscriber.php @@ -5,7 +5,7 @@ use Miracode\StripeBundle\Event\StripeEvent; use Miracode\StripeBundle\Manager\ModelManagerInterface; use Stripe\StripeObject; -use Symfony\Contracts\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; class StripeEventSubscriber implements EventSubscriberInterface { From 6d965aeaffcb11c63d1693c09e0c0205ecbce65a Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Sat, 24 Oct 2020 23:49:21 +0100 Subject: [PATCH 33/61] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a386bc2..875319e 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ This bundle tested on Symfony versions 2.7, 2.8, 3.1, 3.3, 3.4, 4.0. Compatible [![Build Status](https://travis-ci.org/mirovskyi/stripe-bundle.svg?branch=1.0)](https://travis-ci.org/mirovskyi/stripe-bundle) +Currently using this bundle for payments at (https://www.parolla.ie)](https://www.parolla.ie) and (https://tools.parolla.ie)](https://tools.parolla.ie) + Installation ------------ @@ -274,4 +276,4 @@ Also you can use trait `Miracode\StripeBundle\Model\Traits\SafeDeleteTrait` for License ------- -This bundle is released under the MIT license. See the included [LICENSE](LICENSE) file for more information. \ No newline at end of file +This bundle is released under the MIT license. See the included [LICENSE](LICENSE) file for more information. From 6550c18dda6e4ef7177c9da6cc26943ab5321237 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Mon, 21 Dec 2020 19:10:15 +0000 Subject: [PATCH 34/61] Update controller for symfony5 --- Controller/WebhookController.php | 4 ++-- Event/StripeEvent.php | 2 +- Manager/Doctrine/DoctrineORMModelManager.php | 5 +++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Controller/WebhookController.php b/Controller/WebhookController.php index 5c53a69..2faf8e7 100644 --- a/Controller/WebhookController.php +++ b/Controller/WebhookController.php @@ -8,13 +8,13 @@ use Stripe\Error\SignatureVerification; use Stripe\Exception\SignatureVerificationException; use Stripe\Webhook; -use Symfony\Bundle\FrameworkBundle\Controller\Controller; +use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Stripe\Event as StripeEventApi; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; -class WebhookController extends Controller +class WebhookController extends AbstractController { /** * @param Request $request diff --git a/Event/StripeEvent.php b/Event/StripeEvent.php index a4c2fe8..022cb07 100644 --- a/Event/StripeEvent.php +++ b/Event/StripeEvent.php @@ -4,7 +4,7 @@ use Miracode\StripeBundle\StripeException; use Stripe\StripeObject; -use Symfony\Component\EventDispatcher\Event; +use Symfony\Contracts\EventDispatcher\Event; class StripeEvent extends Event { diff --git a/Manager/Doctrine/DoctrineORMModelManager.php b/Manager/Doctrine/DoctrineORMModelManager.php index a8ac75c..f7b5342 100644 --- a/Manager/Doctrine/DoctrineORMModelManager.php +++ b/Manager/Doctrine/DoctrineORMModelManager.php @@ -3,6 +3,7 @@ namespace Miracode\StripeBundle\Manager\Doctrine; use Doctrine\Common\Persistence\ObjectManager; +use Doctrine\ORM\EntityManagerInterface; use Miracode\StripeBundle\Manager\ModelManagerInterface; use Miracode\StripeBundle\Model\AbstractCustomerModel; use Miracode\StripeBundle\Model\AbstractProductModel; @@ -32,12 +33,12 @@ class DoctrineORMModelManager implements ModelManagerInterface /** * DoctrineORMModelManager constructor. - * @param ObjectManager $objectManager + * @param EntityManagerInterface $objectManager * @param TransformerInterface $transformer * @param array $modelClasses */ public function __construct( - ObjectManager $objectManager, + EntityManagerInterface $objectManager, TransformerInterface $transformer, $modelClasses ) { From cebab68163a361a69a8977182db4d183ccfc1357 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Sun, 31 Jan 2021 17:45:49 +0000 Subject: [PATCH 35/61] Register webhook contoller as service --- Resources/config/services.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Resources/config/services.xml b/Resources/config/services.xml index 76d8dd4..c3f3abb 100755 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -5,6 +5,12 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> + + + + + + From 545d98efa55016b3e14429d6b6bac108e271c39b Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Sun, 31 Jan 2021 17:46:34 +0000 Subject: [PATCH 36/61] Change naming format of service --- Resources/config/routing.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/config/routing.xml b/Resources/config/routing.xml index 4f56ce3..5acc04d 100755 --- a/Resources/config/routing.xml +++ b/Resources/config/routing.xml @@ -5,6 +5,6 @@ xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd"> - MiracodeStripeBundle:Webhook:handle + Miracode\StripeBundle\Controller\WebhookController::handleAction From 31c5c740d9559d850b50fc3fb92e1a91af0598d4 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Mon, 1 Feb 2021 21:10:06 +0000 Subject: [PATCH 37/61] Update WebhookController.php --- Controller/WebhookController.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Controller/WebhookController.php b/Controller/WebhookController.php index 2faf8e7..95c9194 100755 --- a/Controller/WebhookController.php +++ b/Controller/WebhookController.php @@ -9,6 +9,7 @@ use Stripe\Exception\SignatureVerificationException; use Stripe\Webhook; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Stripe\Event as StripeEventApi; @@ -16,6 +17,14 @@ class WebhookController extends AbstractController { + + private $eventDispatcher; + + public function __construct(EventDispatcher $eventDispatcher) + { + $this->eventDispatcher = $eventDispatcher; + } + /** * @param Request $request * @@ -73,9 +82,7 @@ public function handleAction(Request $request) } $event = new StripeEvent($stripeEventObject); - $this - ->get('event_dispatcher') - ->dispatch('stripe.' . $stripeEventObject->type, $event); + $this->eventDispatcher->dispatch($event, 'stripe.' . $stripeEventObject->type); return new Response(); } From 34bfb037bcebc1fb7fee3e7a4ef00449161dd72f Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Mon, 1 Feb 2021 21:11:24 +0000 Subject: [PATCH 38/61] Update services.xml --- Resources/config/services.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Resources/config/services.xml b/Resources/config/services.xml index c3f3abb..a0cbd74 100755 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -5,7 +5,8 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - + + @@ -18,5 +19,4 @@ %miracode_stripe.secret_key% - From 1abadbee2d609198bd7b16201bbd96bcca2839cd Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Tue, 9 Feb 2021 14:47:35 +0000 Subject: [PATCH 39/61] Update WebhookController.php Change EventDispatcher to use Symfony\Component\EventDispatcher\EventDispatcherInterface; --- Controller/WebhookController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Controller/WebhookController.php b/Controller/WebhookController.php index 95c9194..7d9ebbd 100755 --- a/Controller/WebhookController.php +++ b/Controller/WebhookController.php @@ -9,7 +9,7 @@ use Stripe\Exception\SignatureVerificationException; use Stripe\Webhook; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; -use Symfony\Component\EventDispatcher\EventDispatcher; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Stripe\Event as StripeEventApi; @@ -20,7 +20,7 @@ class WebhookController extends AbstractController private $eventDispatcher; - public function __construct(EventDispatcher $eventDispatcher) + public function __construct(EventDispatcherInterface $eventDispatcher) { $this->eventDispatcher = $eventDispatcher; } From 4852a90f43d308d463241671b4641f932b638b1d Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Sun, 20 Mar 2022 14:15:29 +0000 Subject: [PATCH 40/61] Provide return type for symfony 6 --- DependencyInjection/Configuration.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 03fc702..2c359e3 100755 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -15,7 +15,7 @@ class Configuration implements ConfigurationInterface /** * {@inheritdoc} */ - public function getConfigTreeBuilder() + public function getConfigTreeBuilder(): TreeBuilder { $treeBuilder = new TreeBuilder('miracode_stripe'); From 34e574d35f91f51d32f04e7d588d65668025f00a Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Fri, 15 Apr 2022 20:48:09 +0100 Subject: [PATCH 41/61] Update StripeClient.php --- Stripe/StripeClient.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Stripe/StripeClient.php b/Stripe/StripeClient.php index 47579cd..667af33 100755 --- a/Stripe/StripeClient.php +++ b/Stripe/StripeClient.php @@ -514,7 +514,7 @@ public function createPlan($productId, $interval, $currency = null, $parameters * @param array $parameters Additional parameters to pass to the constructor * @return Coupon */ - public function createCoupon($id, $duration, $isPercentage = true, $discount, $parameters = []) + public function createCoupon($id, $duration, $isPercentage, $discount, $parameters = []) { $data = [ From 992039ba58e56fdebe9c4976d776470f9d823b56 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Wed, 12 Jul 2023 11:33:17 +0100 Subject: [PATCH 42/61] Add Payout object. --- Event/StripeEvent.php | 3 + Model/AbstractInvoiceModel.php | 26 ++ Model/AbstractPayoutModel.php | 243 ++++++++++++++++++ .../model/AbstractPayoutModel.orm.xml | 19 ++ 4 files changed, 291 insertions(+) create mode 100755 Model/AbstractPayoutModel.php create mode 100755 Resources/config/doctrine/model/AbstractPayoutModel.orm.xml diff --git a/Event/StripeEvent.php b/Event/StripeEvent.php index 022cb07..aeea11b 100755 --- a/Event/StripeEvent.php +++ b/Event/StripeEvent.php @@ -47,11 +47,14 @@ class StripeEvent extends Event const PLAN_DELETED = 'stripe.plan.deleted'; const PLAN_UPDATED = 'stripe.plan.updated'; const PAYMENT_INTENT_SUCCEEDED = 'stripe.payment_intent.succeeded'; + const PAYOUT_PAID = 'stripe.payout.paid'; + const REPORT_RUN_SUCCEEDED = 'stripe.reporting.report_run.succeeded'; const SOURCE_CANCELED = 'stripe.source.canceled'; const SOURCE_CHARGEABLE = 'stripe.source.chargeable'; const SOURCE_FAILED = 'stripe.source.failed'; const TAX_RATE_CREATED = 'stripe.tax_rate.created'; const TAX_RATE_UPDATED = 'stripe.tax_rate.updated'; + const CHECKOUT_SESSION_COMPLETED = 'stripe.checkout.session.completed'; /** * @var StripeObject diff --git a/Model/AbstractInvoiceModel.php b/Model/AbstractInvoiceModel.php index a895508..516e0b8 100755 --- a/Model/AbstractInvoiceModel.php +++ b/Model/AbstractInvoiceModel.php @@ -49,6 +49,13 @@ abstract class AbstractInvoiceModel extends StripeModel */ protected $billing; + /** + * @StripeObjectParam(name="billing_reason") + * + * @var string + */ + protected $billingReason; + /** * @StripeObjectParam * @@ -386,6 +393,25 @@ public function setBilling($billing) return $this; } + /** + * @return string + */ + public function getBillingReason(): string + { + return $this->billingReason; + } + + /** + * @param string $billingReason + * @return AbstractInvoiceModel + */ + public function setBillingReason(string $billingReason): AbstractInvoiceModel + { + $this->billingReason = $billingReason; + + return $this; + } + /** * @return string */ diff --git a/Model/AbstractPayoutModel.php b/Model/AbstractPayoutModel.php new file mode 100755 index 0000000..3b969fb --- /dev/null +++ b/Model/AbstractPayoutModel.php @@ -0,0 +1,243 @@ +amount; + } + + /** + * @param int $amount + * @return AbstractPayoutModel + */ + public function setAmount($amount) + { + $this->amount = $amount; + + return $this; + } + + /** + * @return int + */ + public function getCreated() + { + return $this->created; + } + + /** + * @param int $created + * @return AbstractPayoutModel + */ + public function setCreated($created) + { + $this->created = $created; + + return $this; + } + + /** + * @return int + */ + public function getArrivalDate() + { + return $this->arrival_date; + } + + /** + * @param int $arrival_date + * @return AbstractPayoutModel + */ + public function setArrivalDate($arrival_date) + { + $this->arrival_date = $arrival_date; + + return $this; + } + + /** + * @return string + */ + public function getCurrency() + { + return $this->currency; + } + + /** + * @param string $currency + * @return AbstractPayoutModel + */ + public function setCurrency($currency) + { + $this->currency = $currency; + + return $this; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } + + /** + * @param string $description + * @return AbstractPayoutModel + */ + public function setDescription($description) + { + $this->description = $description; + + return $this; + } + + /** + * @return bool + */ + public function isLivemode() + { + return $this->livemode; + } + + /** + * @param bool $livemode + * @return AbstractPayoutModel + */ + public function setLivemode($livemode) + { + $this->livemode = $livemode; + + return $this; + } + + /** + * @return array + */ + public function getMetadata() + { + return $this->metadata; + } + + /** + * @param array $metadata + * @return AbstractPayoutModel + */ + public function setMetadata($metadata) + { + $this->metadata = $metadata; + + return $this; + } + + /** + * @return string + */ + public function getType() + { + return $this->type; + } + + /** + * @param string $type + * @return AbstractPayoutModel + */ + public function setType($type) + { + $this->type = $type; + + return $this; + } + + /** + * @return string + */ + public function getStatus() + { + return $this->status; + } + + /** + * @param string $status + * @return AbstractPayoutModel + */ + public function setStatus($status) + { + $this->status = $status; + + return $this; + } +} diff --git a/Resources/config/doctrine/model/AbstractPayoutModel.orm.xml b/Resources/config/doctrine/model/AbstractPayoutModel.orm.xml new file mode 100755 index 0000000..4155b18 --- /dev/null +++ b/Resources/config/doctrine/model/AbstractPayoutModel.orm.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file From 0f07c1f07df7dffe7716dd1f7ebcca88a9480746 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Wed, 12 Jul 2023 11:57:01 +0100 Subject: [PATCH 43/61] Add Payout object. --- Model/AbstractPayoutModel.php | 10 +++++----- .../config/doctrine/model/AbstractPayoutModel.orm.xml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Model/AbstractPayoutModel.php b/Model/AbstractPayoutModel.php index 3b969fb..f6c1b53 100755 --- a/Model/AbstractPayoutModel.php +++ b/Model/AbstractPayoutModel.php @@ -22,11 +22,11 @@ abstract class AbstractPayoutModel extends StripeModel protected $created; /** - * @StripeObjectParam + * @StripeObjectParam(name="arrival_date") * * @var int */ - protected $arrival_date; + protected $arrivalDate; /** * @StripeObjectParam @@ -113,16 +113,16 @@ public function setCreated($created) */ public function getArrivalDate() { - return $this->arrival_date; + return $this->arrivalDate; } /** * @param int $arrival_date * @return AbstractPayoutModel */ - public function setArrivalDate($arrival_date) + public function setArrivalDate($arrivalDate) { - $this->arrival_date = $arrival_date; + $this->arrivalDate = $arrivalDate; return $this; } diff --git a/Resources/config/doctrine/model/AbstractPayoutModel.orm.xml b/Resources/config/doctrine/model/AbstractPayoutModel.orm.xml index 4155b18..f55a7d6 100755 --- a/Resources/config/doctrine/model/AbstractPayoutModel.orm.xml +++ b/Resources/config/doctrine/model/AbstractPayoutModel.orm.xml @@ -6,7 +6,7 @@ - + From 50878c9a11ea337226d9ffd708f8b1501877102d Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Wed, 12 Jul 2023 11:57:13 +0100 Subject: [PATCH 44/61] Add Payout object. --- Model/AbstractPayoutModel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Model/AbstractPayoutModel.php b/Model/AbstractPayoutModel.php index f6c1b53..b83b58e 100755 --- a/Model/AbstractPayoutModel.php +++ b/Model/AbstractPayoutModel.php @@ -117,7 +117,7 @@ public function getArrivalDate() } /** - * @param int $arrival_date + * @param int $arrivalDate * @return AbstractPayoutModel */ public function setArrivalDate($arrivalDate) From 21657cb094478261e6a450ec69ebdb95148141b2 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Wed, 12 Jul 2023 15:58:03 +0100 Subject: [PATCH 45/61] Add Payout object. --- DependencyInjection/Configuration.php | 1 + 1 file changed, 1 insertion(+) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 2c359e3..5705bfb 100755 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -60,6 +60,7 @@ public function getConfigTreeBuilder(): TreeBuilder ->scalarNode('tax_id')->cannotBeEmpty()->end() ->scalarNode('discount')->cannotBeEmpty()->end() ->scalarNode('invoice')->cannotBeEmpty()->end() + ->scalarNode('payout')->cannotBeEmpty()->end() ->scalarNode('product')->cannotBeEmpty()->end() ->scalarNode('plan')->cannotBeEmpty()->end() ->scalarNode('refund')->cannotBeEmpty()->end() From bc4a3e5133137417c592646175855859eb7c8cd0 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Wed, 23 Aug 2023 12:17:35 +0100 Subject: [PATCH 46/61] Add stripe api version in params file. Update some stripe events --- DependencyInjection/Configuration.php | 3 + .../MiracodeStripeExtension.php | 5 + Event/StripeEvent.php | 109 ++++++++++-------- README.md | 12 +- Stripe/StripeClient.php | 6 +- 5 files changed, 80 insertions(+), 55 deletions(-) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 5705bfb..7288e4c 100755 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -30,6 +30,9 @@ public function getConfigTreeBuilder(): TreeBuilder $rootNode ->children() + ->scalarNode('api_version') + ->defaultNull() + ->end() ->scalarNode('secret_key') ->isRequired() ->cannotBeEmpty() diff --git a/DependencyInjection/MiracodeStripeExtension.php b/DependencyInjection/MiracodeStripeExtension.php index 2b394e7..6fd05a8 100755 --- a/DependencyInjection/MiracodeStripeExtension.php +++ b/DependencyInjection/MiracodeStripeExtension.php @@ -40,6 +40,11 @@ public function load(array $configs, ContainerBuilder $container) $config['webhook_secret'] ); + $container->setParameter( + 'miracode_stripe.api_version', + $config['api_version'] + ); + if (!empty($config['database']) && !empty($config['database']['model'])) { if (!empty($config['database']['model_transformer'])) { $container->setAlias( diff --git a/Event/StripeEvent.php b/Event/StripeEvent.php index aeea11b..977d6a1 100755 --- a/Event/StripeEvent.php +++ b/Event/StripeEvent.php @@ -8,53 +8,68 @@ class StripeEvent extends Event { - const CHARGE_CAPTURED = 'stripe.charge.captured'; - const CHARGE_FAILED = 'stripe.charge.failed'; - const CHARGE_PENDING = 'charge.pending'; - const CHARGE_REFUNDED = 'stripe.charge.refunded'; - const CHARGE_SUCCEEDED = 'stripe.charge.succeeded'; - const CHARGE_UPDATED = 'stripe.charge.updated'; - const COUPON_CREATED = 'stripe.coupon.created'; - const COUPON_DELETED = 'stripe.coupon.deleted'; - const COUPON_UPDATED = 'stripe.coupon.updated'; - const CUSTOMER_CREATED = 'stripe.customer.created'; - const CUSTOMER_DELETED = 'stripe.customer.deleted'; - const CUSTOMER_UPDATED = 'stripe.customer.updated'; - const CUSTOMER_DISCOUNT_CREATED = 'stripe.customer.discount.created'; - const CUSTOMER_DISCOUNT_DELETED = 'stripe.customer.discount.deleted'; - const CUSTOMER_DISCOUNT_UPDATED = 'stripe.customer.discount.updated'; - const CUSTOMER_SOURCE_CREATED = 'stripe.customer.source.created'; - const CUSTOMER_SOURCE_DELETED = 'stripe.customer.source.deleted'; - const CUSTOMER_SOURCE_UPDATED = 'stripe.customer.source.updated'; - const CUSTOMER_SUBSCRIPTION_CREATED = 'stripe.customer.subscription.created'; - const CUSTOMER_SUBSCRIPTION_DELETED = 'stripe.customer.subscription.deleted'; - const CUSTOMER_SUBSCRIPTION_UPDATED = 'stripe.customer.subscription.updated'; - const CUSTOMER_SUBSCRIPTION_TRIAL_WILL_END = 'stripe.customer.subscription.trial_will_end'; - const CUSTOMER_TAX_ID_CREATED = 'stripe.customer.tax_id.created'; - const CUSTOMER_TAX_ID_UPDATED = 'stripe.customer.tax_id.updated'; - const INVOICE_CREATED = 'stripe.invoice.created'; - const INVOICE_DELETED = 'stripe.invoice.deleted'; - const INVOICE_FINALIZED = 'stripe.invoice.finalized'; - const INVOICE_ITEM_UPDATED = 'stripe.invoiceitem.updated'; - const INVOICE_PAYMENT_ACTION_REQUIRED = 'stripe.invoice.payment_action_required'; - const INVOICE_PAYMENT_FAILED = 'stripe.invoice.payment_failed'; - const INVOICE_PAYMENT_SUCCEEDED = 'stripe.invoice.payment_succeeded'; - const INVOICE_SENT = 'stripe.invoice.sent'; - const INVOICE_UPCOMING = 'stripe.invoice.upcoming'; - const INVOICE_UPDATED = 'stripe.invoice.updated'; - const INVOICE_VOIDED = 'stripe.invoice.voided'; - const PLAN_CREATED = 'stripe.plan.created'; - const PLAN_DELETED = 'stripe.plan.deleted'; - const PLAN_UPDATED = 'stripe.plan.updated'; - const PAYMENT_INTENT_SUCCEEDED = 'stripe.payment_intent.succeeded'; - const PAYOUT_PAID = 'stripe.payout.paid'; - const REPORT_RUN_SUCCEEDED = 'stripe.reporting.report_run.succeeded'; - const SOURCE_CANCELED = 'stripe.source.canceled'; - const SOURCE_CHARGEABLE = 'stripe.source.chargeable'; - const SOURCE_FAILED = 'stripe.source.failed'; - const TAX_RATE_CREATED = 'stripe.tax_rate.created'; - const TAX_RATE_UPDATED = 'stripe.tax_rate.updated'; - const CHECKOUT_SESSION_COMPLETED = 'stripe.checkout.session.completed'; + public const CHARGE_CAPTURED = 'stripe.charge.captured'; + public const CHARGE_FAILED = 'stripe.charge.failed'; + public const CHARGE_PENDING = 'charge.pending'; + public const CHARGE_REFUNDED = 'stripe.charge.refunded'; + public const CHARGE_SUCCEEDED = 'stripe.charge.succeeded'; + public const CHARGE_UPDATED = 'stripe.charge.updated'; + public const COUPON_CREATED = 'stripe.coupon.created'; + public const COUPON_DELETED = 'stripe.coupon.deleted'; + public const COUPON_UPDATED = 'stripe.coupon.updated'; + public const CUSTOMER_CREATED = 'stripe.customer.created'; + public const CUSTOMER_DELETED = 'stripe.customer.deleted'; + public const CUSTOMER_UPDATED = 'stripe.customer.updated'; + public const CUSTOMER_DISCOUNT_CREATED = 'stripe.customer.discount.created'; + public const CUSTOMER_DISCOUNT_DELETED = 'stripe.customer.discount.deleted'; + public const CUSTOMER_DISCOUNT_UPDATED = 'stripe.customer.discount.updated'; + public const CUSTOMER_SOURCE_CREATED = 'stripe.customer.source.created'; + public const CUSTOMER_SOURCE_DELETED = 'stripe.customer.source.deleted'; + public const CUSTOMER_SOURCE_UPDATED = 'stripe.customer.source.updated'; + public const CUSTOMER_SUBSCRIPTION_CREATED = 'stripe.customer.subscription.created'; + public const CUSTOMER_SUBSCRIPTION_DELETED = 'stripe.customer.subscription.deleted'; + public const CUSTOMER_SUBSCRIPTION_UPDATED = 'stripe.customer.subscription.updated'; + public const CUSTOMER_SUBSCRIPTION_TRIAL_WILL_END = 'stripe.customer.subscription.trial_will_end'; + public const CUSTOMER_TAX_ID_CREATED = 'stripe.customer.tax_id.created'; + public const CUSTOMER_TAX_ID_UPDATED = 'stripe.customer.tax_id.updated'; + public const INVOICE_CREATED = 'stripe.invoice.created'; + public const INVOICE_DELETED = 'stripe.invoice.deleted'; + public const INVOICE_FINALIZED = 'stripe.invoice.finalized'; + public const INVOICE_ITEM_UPDATED = 'stripe.invoiceitem.updated'; + public const INVOICE_PAYMENT_ACTION_REQUIRED = 'stripe.invoice.payment_action_required'; + public const INVOICE_PAYMENT_FAILED = 'stripe.invoice.payment_failed'; + public const INVOICE_PAYMENT_SUCCEEDED = 'stripe.invoice.payment_succeeded'; + public const INVOICE_SENT = 'stripe.invoice.sent'; + public const INVOICE_UPCOMING = 'stripe.invoice.upcoming'; + public const INVOICE_UPDATED = 'stripe.invoice.updated'; + public const INVOICE_VOIDED = 'stripe.invoice.voided'; + public const PLAN_CREATED = 'stripe.plan.created'; + public const PLAN_DELETED = 'stripe.plan.deleted'; + public const PLAN_UPDATED = 'stripe.plan.updated'; + public const PAYMENT_INTENT_AMOUNT_CAPTURABLE_UPDATED = 'stripe.payment_intent.amount_capturable_updated'; + public const PAYMENT_INTENT_CANCELLED = 'stripe.payment_intent.canceled'; + public const PAYMENT_INTENT_CREATED = 'stripe.payment_intent.created'; + public const PAYMENT_INTENT_PAYMENT_FILED = 'stripe.payment_intent.payment_failed'; + public const PAYMENT_INTENT_PROCESSING = 'stripe.payment_intent.processing'; + public const PAYMENT_INTENT_REQURIES_ACTION = 'stripe.payment_intent.requires_action'; + public const PAYMENT_INTENT_SUCCEEDED = 'stripe.payment_intent.succeeded'; + public const PAYMENT_METHOD_ATTACHED = 'stripe.payment_method.attached'; + public const PAYMENT_METHOD_DETACHED = 'stripe.payment_method.detached'; + public const PAYMENT_METHOD_UPDATED = 'stripe.payment_method.updated'; + public const PAYMENT_METHOD_AUTOMATICALLY_UPDATED = 'stripe.payment_method.automatically_updated'; + public const PAYOUT_PAID = 'stripe.payout.paid'; + public const REPORT_RUN_SUCCEEDED = 'stripe.reporting.report_run.succeeded'; + public const SETUP_INTENT_CANCELED = 'stripe.setup_intent.canceled'; + public const SETUP_INTENT_CREATED = 'stripe.setup_intent.created'; + public const SETUP_INTENT_REQUIRES_ACTION = 'stripe.setup_intent.requires_action'; + public const SETUP_INTENT_SETUP_FILED = 'stripe.setup_intent.setup_failed'; + public const SETUP_INTENT_SUCCEEDED = 'stripe.setup_intent.succeeded'; + public const SOURCE_CANCELED = 'stripe.source.canceled'; + public const SOURCE_CHARGEABLE = 'stripe.source.chargeable'; + public const SOURCE_FAILED = 'stripe.source.failed'; + public const TAX_RATE_CREATED = 'stripe.tax_rate.created'; + public const TAX_RATE_UPDATED = 'stripe.tax_rate.updated'; + public const CHECKOUT_SESSION_COMPLETED = 'stripe.checkout.session.completed'; /** * @var StripeObject diff --git a/README.md b/README.md index 7b4108a..db0e53a 100755 --- a/README.md +++ b/README.md @@ -2,12 +2,6 @@ MiracodeStripeBundle ==================== The MiracodeStripeBundle integrates Stripe PHP SDK to your Symfony project. -Also you can configure bundle to save Stripe data in database. -You are free to choose what Stripe objects will be stored. - -This bundle tested on Symfony versions 2.7, 2.8, 3.1, 3.3, 3.4, 4.0. Compatible with Symfony >=2.4 - -[![Build Status](https://travis-ci.org/mirovskyi/stripe-bundle.svg?branch=1.0)](https://travis-ci.org/mirovskyi/stripe-bundle) Currently using this bundle for payments at (https://www.parolla.ie)](https://www.parolla.ie) and (https://tools.parolla.ie)](https://tools.parolla.ie) @@ -43,11 +37,15 @@ return [ Miracode\StripeBundle\MiracodeStripeBundle::class => ['all' => true], ]; ``` -And set-up required configuration +And set-up required configuration. + +Note that the api version will override your stripe default version. Use this if migrating stripe API version, leave null +if you want to let Stripe use the developer GUI default version. ``` yaml # app/config/config.yml (or config/packages/miracode_stripe.yaml for Symfony >=3.4) miracode_stripe: + api_version: "2019-10-17" secret_key: "%stripe_secret_key%" ``` diff --git a/Stripe/StripeClient.php b/Stripe/StripeClient.php index 667af33..d41f6b6 100755 --- a/Stripe/StripeClient.php +++ b/Stripe/StripeClient.php @@ -30,10 +30,14 @@ */ class StripeClient extends Stripe { - public function __construct($stripeApiKey) + public function __construct(string $stripeApiKey, $apiVersion = null) { self::setApiKey($stripeApiKey); + if(null === $apiVersion){ + self::setApiVersion($apiVersion); + } + return $this; } From ceee51d022f4bea774b614c587b1dc6e92cf1a7f Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Fri, 15 Dec 2023 18:04:53 +0000 Subject: [PATCH 47/61] Add stripe api version in params file. Update some stripe events --- DependencyInjection/Configuration.php | 41 +- .../MiracodeStripeExtension.php | 55 ++- Resources/config/services.xml | 11 +- Stripe/StripeClient.php | 424 +++++++----------- Stripe/StripeObjectType.php | 25 +- composer.json | 14 +- 6 files changed, 256 insertions(+), 314 deletions(-) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 7288e4c..16b608e 100755 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -18,7 +18,7 @@ class Configuration implements ConfigurationInterface public function getConfigTreeBuilder(): TreeBuilder { $treeBuilder = new TreeBuilder('miracode_stripe'); - + if (method_exists($treeBuilder, 'getRootNode')) { $rootNode = $treeBuilder->getRootNode(); } else { @@ -30,19 +30,48 @@ public function getConfigTreeBuilder(): TreeBuilder $rootNode ->children() + ->scalarNode('environment') + ->defaultFalse('prod') + ->end() ->scalarNode('api_version') ->defaultNull() ->end() - ->scalarNode('secret_key') - ->isRequired() - ->cannotBeEmpty() + ->arrayNode('prod') + ->children() + ->scalarNode('secret_key') + ->isRequired() + ->cannotBeEmpty() + ->end() + ->scalarNode('perishable_key') + ->isRequired() + ->cannotBeEmpty() + ->end() + ->scalarNode('webhook_secret') + ->defaultNull() + ->end() + ->end() ->end() - ->scalarNode('webhook_secret') - ->defaultNull() + ->arrayNode('test') + ->children() + ->scalarNode('secret_key') + ->isRequired() + ->cannotBeEmpty() + ->end() + ->scalarNode('perishable_key') + ->isRequired() + ->cannotBeEmpty() + ->end() + ->scalarNode('webhook_secret') + ->defaultNull() + ->end() + ->end() ->end() ->booleanNode('use_bundle_subscriber') ->defaultTrue() ->end() + ->booleanNode('verify_stripe_signature') + ->defaultTrue() + ->end() ->arrayNode('database') ->children() ->scalarNode('driver') diff --git a/DependencyInjection/MiracodeStripeExtension.php b/DependencyInjection/MiracodeStripeExtension.php index 6fd05a8..d45e0e0 100755 --- a/DependencyInjection/MiracodeStripeExtension.php +++ b/DependencyInjection/MiracodeStripeExtension.php @@ -2,15 +2,15 @@ namespace Miracode\StripeBundle\DependencyInjection; -use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Loader; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\HttpKernel\DependencyInjection\Extension; -use Symfony\Component\DependencyInjection\Loader; /** - * This is the class that loads and manages your bundle configuration + * This is the class that loads and manages your bundle configuration. * * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html} */ @@ -30,14 +30,44 @@ public function load(array $configs, ContainerBuilder $container) ); $loader->load('services.xml'); + $env = $config['environment']; + + $secret = $config['prod']['secret_key']; + $perishableKey = $config['prod']['perishable_key']; + $webhookSecret = $config['prod']['webhook_secret']; + $testSecret = $config['test']['secret_key']; + $testPerishableKey = $config['test']['perishable_key']; + $testWebhookSecret = $config['test']['webhook_secret']; + $container->setParameter( - 'miracode_stripe.secret_key', - $config['secret_key'] + 'miracode_stripe.environment', + $env ); + $container->setParameter( + 'miracode_stripe.test.secret_key', + $testSecret + ); + $container->setParameter( + 'miracode_stripe.test.perishable_key', + $testPerishableKey + ); + $container->setParameter( + 'miracode_stripe.test.webhook_secret', + $testWebhookSecret + ); + + $container->setParameter( + 'miracode_stripe.secret_key', + $secret + ); + $container->setParameter( + 'miracode_stripe.perishable_key', + $perishableKey + ); $container->setParameter( 'miracode_stripe.webhook_secret', - $config['webhook_secret'] + $webhookSecret ); $container->setParameter( @@ -58,9 +88,8 @@ public function load(array $configs, ContainerBuilder $container) ); } if ($this->configureDatabase($config['database'], $container)) { - // If the bundle event listener is to be used. - if($config['use_bundle_subscriber'] === true) { + if (true === $config['use_bundle_subscriber']) { $loader->load('listener.xml'); } } @@ -69,12 +98,12 @@ public function load(array $configs, ContainerBuilder $container) /** * @param array $config - * @param ContainerBuilder $container * * @return bool */ - private function configureDatabase($config, ContainerBuilder $container) { - if ($config['driver'] == 'orm') { + private function configureDatabase($config, ContainerBuilder $container) + { + if ('orm' == $config['driver']) { if (!isset($config['object_manager'])) { $config['object_manager'] = 'doctrine.orm.entity_manager'; } @@ -93,7 +122,7 @@ private function configureDatabase($config, ContainerBuilder $container) { $definition->setArguments([ new Reference('miracode_stripe.object_manager'), new Reference('miracode_stripe.model_transformer'), - '%miracode_stripe.model_classes%' + '%miracode_stripe.model_classes%', ]); $definition->setPublic(true); $container->setDefinition( @@ -103,7 +132,7 @@ private function configureDatabase($config, ContainerBuilder $container) { return true; } - //TODO: support other drivers + // TODO: support other drivers return false; } diff --git a/Resources/config/services.xml b/Resources/config/services.xml index a0cbd74..612c01c 100755 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -8,7 +8,7 @@ - + @@ -16,7 +16,14 @@ class="Miracode\StripeBundle\Transformer\AnnotationTransformer"> - %miracode_stripe.secret_key% + + %miracode_stripe.environment% + %miracode_stripe.secret_key% + %miracode_stripe.perishable_key% + %miracode_stripe.test.secret_key% + %miracode_stripe.test.perishable_key% + %miracode_stripe.api_version% + diff --git a/Stripe/StripeClient.php b/Stripe/StripeClient.php index d41f6b6..efd1d8c 100755 --- a/Stripe/StripeClient.php +++ b/Stripe/StripeClient.php @@ -1,196 +1,78 @@ $paymentToken, - 'email' => $customerEmail + $customer = $this->customers->create([ + 'source' => $paymentToken, + 'email' => $customerEmail, ]); $data = [ - 'customer' => $customer->id, - 'plan' => $planId, + 'customer' => $customer->id, + 'plan' => $planId, ]; if ($couponId) { $data['coupon'] = $couponId; } - $subscription = Subscription::create($data); + $subscription = $this->subscriptions->create($data); return $customer; } @@ -198,109 +80,107 @@ public function subscribeCustomerToPlan($planId, $paymentToken, $customerEmail, /** * Associate an existing Customer object to an existing Plan. * - * @throws HttpException: - * - If the customerId is invalid (the customer does not exists...) - * - If the planId is invalid (the plan does not exists...) - * * @see https://stripe.com/docs/api#create_subscription * * @param string $customerId: The customer ID as defined in your Stripe dashboard - * @param string $planId: The plan ID as defined in your Stripe dashboard - * @param array $parameters: Optional additional parameters, the complete list is available here: https://stripe.com/docs/api#create_subscription + * @param string $planId: The plan ID as defined in your Stripe dashboard + * @param array $parameters: Optional additional parameters, the complete list is available here: https://stripe.com/docs/api#create_subscription * * @return Subscription + * + * @throws HttpException: + * - If the customerId is invalid (the customer does not exists...) + * - If the planId is invalid (the plan does not exists...) */ public function subscribeExistingCustomerToPlan($customerId, $planId, $parameters = []) { $data = [ - 'customer' => $customerId, - 'plan' => $planId + 'customer' => $customerId, + 'plan' => $planId, ]; if (is_array($parameters) && !empty($parameters)) { $data = array_merge($parameters, $data); } - return Subscription::create($data); + return $this->subscriptions->create($data); } /** * Associate an existing Customer object to an existing Plan. * - * @throws HttpException: - * - If the customerId is invalid (the customer does not exists...) - * - If the planId is invalid (the plan does not exists...) - * * @see https://stripe.com/docs/api#create_subscription * * @param string $customerId: The customer ID as defined in your Stripe dashboard - * @param array $items: An Array of Plan items. - * @param array $parameters: Optional additional parameters, the complete list is available here: https://stripe.com/docs/api#create_subscription + * @param array $items: An Array of Plan items + * @param array $parameters: Optional additional parameters, the complete list is available here: https://stripe.com/docs/api#create_subscription * * @return Subscription + * + * @throws HttpException: + * - If the customerId is invalid (the customer does not exists...) + * - If the planId is invalid (the plan does not exists...) */ public function subscribeExistingCustomerToMultiplePlans($customerId, $items = [], $parameters = []) { $data = [ - 'customer' => $customerId, - 'items' => $items + 'customer' => $customerId, + 'items' => $items, ]; if (is_array($parameters) && !empty($parameters)) { $data = array_merge($parameters, $data); } - return Subscription::create($data); + return $this->subscriptions->create($data); } /** - * @param $subscriptionId - * @param $planId - * @param $quantity * @param array $parameters + * * @return SubscriptionItem */ public function createSubscriptionItem($subscriptionId, $planId, $quantity, $parameters = []) { $data = [ - "subscription" => $subscriptionId, - "plan" => $planId, - "quantity" => $quantity, + 'subscription' => $subscriptionId, + 'plan' => $planId, + 'quantity' => $quantity, ]; if (is_array($parameters) && !empty($parameters)) { $data = array_merge($parameters, $data); } - return SubscriptionItem::create($data); + return $this->subscriptionItems->create($data); } /** * Create a new Charge from a payment token, to an optional connected stripe account, with an optional application fee. * - * @throws HttpException: - * - If the payment token is invalid (payment failed) - * * @see https://stripe.com/docs/charges * - * @param int $chargeAmount: The charge amount in cents - * @param string $chargeCurrency: The charge currency to use - * @param string $paymentToken: The payment token returned by the payment form (Stripe.js) + * @param int $chargeAmount: The charge amount in cents + * @param string $chargeCurrency: The charge currency to use + * @param string $paymentToken: The payment token returned by the payment form (Stripe.js) * @param string $stripeAccountId: The connected stripe account ID - * @param int $applicationFee: The fee taken by the platform, in cents - * @param string $description: An optional charge description - * @param array $metadata: An optional array of metadatas + * @param int $applicationFee: The fee taken by the platform, in cents + * @param string $description: An optional charge description + * @param array $metadata: An optional array of metadatas * * @return Charge + * + * @throws HttpException: + * - If the payment token is invalid (payment failed) */ public function createCharge($chargeAmount, $chargeCurrency, $paymentToken, $stripeAccountId = null, $applicationFee = 0, $chargeDescription = '', $chargeMetadata = []) { $chargeOptions = [ - 'amount' => $chargeAmount, - 'currency' => $chargeCurrency, - 'source' => $paymentToken, - 'description' => $chargeDescription, - 'metadata' => $chargeMetadata + 'amount' => $chargeAmount, + 'currency' => $chargeCurrency, + 'source' => $paymentToken, + 'description' => $chargeDescription, + 'metadata' => $chargeMetadata, ]; if ($applicationFee && intval($applicationFee) > 0) { @@ -313,98 +193,98 @@ public function createCharge($chargeAmount, $chargeCurrency, $paymentToken, $str $connectedAccountOptions['stripe_account'] = $stripeAccountId; } - return Charge::create($chargeOptions, $connectedAccountOptions); + return $this->charges->create($chargeOptions, $connectedAccountOptions); } /** * Create a new Destination Charge from a payment token, to a connected stripe account, with an application fee. * - * @throws HttpException: - * - If the payment token is invalid (payment failed) - * * @see https://stripe.com/docs/connect/destination-charges * - * @param int $chargeAmount: The charge amount in cents - * @param string $chargeCurrency: The charge currency to use - * @param string $paymentToken: The payment token returned by the payment form (Stripe.js) - * @param string $stripeAccountId: The connected stripe account ID - * @param int $applicationFee: The fee taken by the platform, in cents + * @param int $chargeAmount: The charge amount in cents + * @param string $chargeCurrency: The charge currency to use + * @param string $paymentToken: The payment token returned by the payment form (Stripe.js) + * @param string $stripeAccountId: The connected stripe account ID + * @param int $applicationFee: The fee taken by the platform, in cents * @param string $chargeDescription: An optional charge description - * @param array $chargeMetadata: An optional array of metadatas + * @param array $chargeMetadata: An optional array of metadatas * * @return Charge + * + * @throws HttpException: + * - If the payment token is invalid (payment failed) */ public function createDestinationCharge($chargeAmount, $chargeCurrency, $paymentToken, $stripeAccountId, $applicationFee, $chargeDescription = '', $chargeMetadata = []) { $chargeOptions = [ - 'amount' => $chargeAmount, - 'currency' => $chargeCurrency, - 'source' => $paymentToken, - 'description' => $chargeDescription, - 'metadata' => $chargeMetadata, - 'destination' => [ + 'amount' => $chargeAmount, + 'currency' => $chargeCurrency, + 'source' => $paymentToken, + 'description' => $chargeDescription, + 'metadata' => $chargeMetadata, + 'destination' => [ 'amount' => $chargeAmount - $applicationFee, - 'account' => $stripeAccountId - ] + 'account' => $stripeAccountId, + ], ]; - return Charge::create($chargeOptions); + return $this->charges->create($chargeOptions); } /** * Create a new Charge from a payment token, to an optional connected stripe account, with an optional application fee. * - * @throws HttpException: - * - If the payment token is invalid (payment failed) - * * @see https://stripe.com/docs/charges#saving-credit-card-details-for-later * * @param string $paymentToken: The payment token returned by the payment form (Stripe.js) - * @param string $email: An optional customer e-mail - * @param array $parameters: Optional additional parameters, the complete list is available here: https://stripe.com/docs/api#create_customer + * @param string $email: An optional customer e-mail + * @param array $parameters: Optional additional parameters, the complete list is available here: https://stripe.com/docs/api#create_customer * * @return Charge + * + * @throws HttpException: + * - If the payment token is invalid (payment failed) */ public function createCustomer($paymentToken, $email = null, $parameters = []) { $data = [ 'source' => $paymentToken, - 'email' => $email + 'email' => $email, ]; if (is_array($parameters) && !empty($parameters)) { $data = array_merge($parameters, $data); } - return Customer::create($data); + return $this->customers->create($data); } /** - * Create a new Charge on an existing Customer object, to an optional connected stripe account, with an optional application fee - * - * @throws HttpException: - * - If the payment token is invalid (payment failed) + * Create a new Charge on an existing Customer object, to an optional connected stripe account, with an optional application fee. * * @see https://stripe.com/docs/charges#saving-credit-card-details-for-later * - * @param int $chargeAmount: The charge amount in cents - * @param string $chargeCurrency: The charge currency to use - * @param string $customerId: The Stripe Customer object ID + * @param int $chargeAmount: The charge amount in cents + * @param string $chargeCurrency: The charge currency to use + * @param string $customerId: The Stripe Customer object ID * @param string $stripeAccountId: The connected stripe account ID - * @param int $applicationFee: The fee taken by the platform, in cents - * @param string $description: An optional charge description - * @param array $metadata: An optional array of metadatas + * @param int $applicationFee: The fee taken by the platform, in cents + * @param string $description: An optional charge description + * @param array $metadata: An optional array of metadatas * * @return Charge + * + * @throws HttpException: + * - If the payment token is invalid (payment failed) */ public function chargeCustomer($chargeAmount, $chargeCurrency, $customerId, $stripeAccountId = null, $applicationFee = 0, $chargeDescription = '', $chargeMetadata = []) { $chargeOptions = [ - 'amount' => $chargeAmount, - 'currency' => $chargeCurrency, - 'customer' => $customerId, - 'description' => $chargeDescription, - 'metadata' => $chargeMetadata + 'amount' => $chargeAmount, + 'currency' => $chargeCurrency, + 'customer' => $customerId, + 'description' => $chargeDescription, + 'metadata' => $chargeMetadata, ]; if ($applicationFee && intval($applicationFee) > 0) { @@ -417,36 +297,36 @@ public function chargeCustomer($chargeAmount, $chargeCurrency, $customerId, $str $connectedAccountOptions['stripe_account'] = $stripeAccountId; } - return Charge::create($chargeOptions, $connectedAccountOptions); + return $this->charges->create($chargeOptions, $connectedAccountOptions); } /** * Create a new Refund on an existing Charge (by its ID). * - * @throws HttpException: - * - If the charge id is invalid (the charge does not exists...) - * - If the charge has already been refunded - * * @see https://stripe.com/docs/connect/direct-charges#issuing-refunds * - * @param string $chargeId: The charge ID - * @param int $refundAmount: The charge amount in cents - * @param array $metadata: optional additional informations about the refund - * @param string $reason: The reason of the refund, either "requested_by_customer", "duplicate" or "fraudulent" - * @param bool $refundApplicationFee: Wether the application_fee should be refunded aswell. - * @param bool $reverseTransfer: Wether the transfer should be reversed - * @param string $stripeAccountId: The optional connected stripe account ID on which charge has been made. + * @param string $chargeId: The charge ID + * @param int $refundAmount: The charge amount in cents + * @param array $metadata: optional additional informations about the refund + * @param string $reason: The reason of the refund, either "requested_by_customer", "duplicate" or "fraudulent" + * @param bool $refundApplicationFee: Wether the application_fee should be refunded aswell + * @param bool $reverseTransfer: Wether the transfer should be reversed + * @param string $stripeAccountId: The optional connected stripe account ID on which charge has been made * * @return Refund + * + * @throws HttpException: + * - If the charge id is invalid (the charge does not exists...) + * - If the charge has already been refunded */ public function refundCharge($chargeId, $refundAmount = null, $metadata = [], $reason = 'requested_by_customer', $refundApplicationFee = true, $reverseTransfer = false, $stripeAccountId = null) { $refundOptions = [ - 'charge' => $chargeId, - 'metadata' => $metadata, - 'reason' => $reason, - 'refund_application_fee' => (bool) $refundApplicationFee, - 'reverse_transfer' => (bool) $reverseTransfer + 'charge' => $chargeId, + 'metadata' => $metadata, + 'reason' => $reason, + 'refund_application_fee' => (bool) $refundApplicationFee, + 'reverse_transfer' => (bool) $reverseTransfer, ]; if ($refundAmount) { @@ -459,16 +339,17 @@ public function refundCharge($chargeId, $refundAmount = null, $metadata = [], $r $connectedAccountOptions['stripe_account'] = $stripeAccountId; } - return Refund::create($refundOptions, $connectedAccountOptions); + return $this->refunds->create($refundOptions, $connectedAccountOptions); } /** - * @param string $name Product Name - * @param string $type 'service' or 'goods' - * @param array $parameters Array of additional parameters to pass to the constructor + * @param string $name Product Name + * @param string $type 'service' or 'goods' + * @param array $parameters Array of additional parameters to pass to the constructor + * * @return Product */ - public function createProduct($name, $type, $parameters =[] ) + public function createProduct($name, $type, $parameters = []) { $data = [ 'name' => $name, @@ -479,54 +360,53 @@ public function createProduct($name, $type, $parameters =[] ) $data = array_merge($parameters, $data); } - return Product::create($data); + return $this->products::create($data); } /** * @param string $productId * @param string $interval - * @param null $currency Currency to billin , defaults to 'eur' - * @param array $parameters + * @param null $currency Currency to billin , defaults to 'eur' + * @param array $parameters + * * @return Plan */ - public function createPlan($productId, $interval, $currency = null, $parameters = [] ) + public function createPlan($productId, $interval, $currency = null, $parameters = []) { - - if($currency === null){ + if (null === $currency) { $currency = 'eur'; } $data = [ 'product' => $productId, 'interval' => $interval, - 'currency' =>$currency, + 'currency' => $currency, ]; if (is_array($parameters) && !empty($parameters)) { $data = array_merge($parameters, $data); } - return Plan::create($data); - + return $this->plans->create($data); } /** - * @param string $id - * @param string $duration - * @param bool $isPercentage True = percentage_type deduction, false = amount_type - * @param int|float $discount The percentage discount, or amount discount - * @param array $parameters Additional parameters to pass to the constructor + * @param string $id + * @param string $duration + * @param bool $isPercentage True = percentage_type deduction, false = amount_type + * @param int|float $discount The percentage discount, or amount discount + * @param array $parameters Additional parameters to pass to the constructor + * * @return Coupon */ public function createCoupon($id, $duration, $isPercentage, $discount, $parameters = []) { - $data = [ - "id" => $id, - "duration" => $duration, + 'id' => $id, + 'duration' => $duration, ]; - if($isPercentage){ + if ($isPercentage) { $data['percent_off'] = $discount; } else { $data['amount_off'] = $discount; @@ -536,6 +416,6 @@ public function createCoupon($id, $duration, $isPercentage, $discount, $paramete $data = array_merge($parameters, $data); } - return Coupon::create($data); + return $this->coupons->create($data); } } diff --git a/Stripe/StripeObjectType.php b/Stripe/StripeObjectType.php index 1481314..c1eda83 100755 --- a/Stripe/StripeObjectType.php +++ b/Stripe/StripeObjectType.php @@ -4,18 +4,15 @@ class StripeObjectType { - /** - * Stripe object types - */ - const CARD = 'card'; - const CHARGE = 'charge'; - const COUPON = 'coupon'; - const CUSTOMER = 'customer'; - const DISCOUNT = 'discount'; - const EVENT = 'event'; - const INVOICE = 'invoice'; - const PLAN = 'plan'; - const REFUND = 'refund'; - const SUBSCRIPTION = 'subscription'; - const COLLECTION = 'list'; + public const CARD = 'card'; + public const CHARGE = 'charge'; + public const COUPON = 'coupon'; + public const CUSTOMER = 'customer'; + public const DISCOUNT = 'discount'; + public const EVENT = 'event'; + public const INVOICE = 'invoice'; + public const PLAN = 'plan'; + public const REFUND = 'refund'; + public const SUBSCRIPTION = 'subscription'; + public const COLLECTION = 'list'; } diff --git a/composer.json b/composer.json index b480d3b..6331bb5 100755 --- a/composer.json +++ b/composer.json @@ -18,16 +18,16 @@ } ], "require": { - "php" : ">=5.4.0", - "symfony/framework-bundle" : ">=2.4", - "symfony/config" : ">=2.3", - "stripe/stripe-php" : ">=3.0", - "doctrine/common" : ">=2.2" + "php" : ">=8.0", + "symfony/framework-bundle" : ">=6.3", + "symfony/config" : ">=6.3", + "stripe/stripe-php" : ">=12.0", + "doctrine/common" : ">=3.2" }, "require-dev": { - "doctrine/orm" : ">=2.2", + "doctrine/orm" : ">=2.10", "symfony/yaml" : "^2.8 || ^3.0 || ^4.0", - "phpunit/phpunit" : "~4.8|~5.0" + "phpunit/phpunit" : "~4.8|~5.0|~6.0" }, "suggest": { "doctrine/orm" : "If you want to save stripe data in database" From fdbc9cdd84e57098cb36aaa9edcfbae943a26a41 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Fri, 15 Dec 2023 18:22:17 +0000 Subject: [PATCH 48/61] Add stripe api version in params file. Update some stripe events --- DependencyInjection/Configuration.php | 41 +- .../MiracodeStripeExtension.php | 55 +-- Resources/config/services.xml | 11 +- Stripe/StripeClient.php | 424 +++++++++++------- Stripe/StripeObjectType.php | 25 +- composer.json | 14 +- 6 files changed, 314 insertions(+), 256 deletions(-) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 16b608e..7288e4c 100755 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -18,7 +18,7 @@ class Configuration implements ConfigurationInterface public function getConfigTreeBuilder(): TreeBuilder { $treeBuilder = new TreeBuilder('miracode_stripe'); - + if (method_exists($treeBuilder, 'getRootNode')) { $rootNode = $treeBuilder->getRootNode(); } else { @@ -30,48 +30,19 @@ public function getConfigTreeBuilder(): TreeBuilder $rootNode ->children() - ->scalarNode('environment') - ->defaultFalse('prod') - ->end() ->scalarNode('api_version') ->defaultNull() ->end() - ->arrayNode('prod') - ->children() - ->scalarNode('secret_key') - ->isRequired() - ->cannotBeEmpty() - ->end() - ->scalarNode('perishable_key') - ->isRequired() - ->cannotBeEmpty() - ->end() - ->scalarNode('webhook_secret') - ->defaultNull() - ->end() - ->end() + ->scalarNode('secret_key') + ->isRequired() + ->cannotBeEmpty() ->end() - ->arrayNode('test') - ->children() - ->scalarNode('secret_key') - ->isRequired() - ->cannotBeEmpty() - ->end() - ->scalarNode('perishable_key') - ->isRequired() - ->cannotBeEmpty() - ->end() - ->scalarNode('webhook_secret') - ->defaultNull() - ->end() - ->end() + ->scalarNode('webhook_secret') + ->defaultNull() ->end() ->booleanNode('use_bundle_subscriber') ->defaultTrue() ->end() - ->booleanNode('verify_stripe_signature') - ->defaultTrue() - ->end() ->arrayNode('database') ->children() ->scalarNode('driver') diff --git a/DependencyInjection/MiracodeStripeExtension.php b/DependencyInjection/MiracodeStripeExtension.php index d45e0e0..6fd05a8 100755 --- a/DependencyInjection/MiracodeStripeExtension.php +++ b/DependencyInjection/MiracodeStripeExtension.php @@ -2,15 +2,15 @@ namespace Miracode\StripeBundle\DependencyInjection; -use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\Definition; -use Symfony\Component\DependencyInjection\Loader; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\HttpKernel\DependencyInjection\Extension; +use Symfony\Component\DependencyInjection\Loader; /** - * This is the class that loads and manages your bundle configuration. + * This is the class that loads and manages your bundle configuration * * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html} */ @@ -30,44 +30,14 @@ public function load(array $configs, ContainerBuilder $container) ); $loader->load('services.xml'); - $env = $config['environment']; - - $secret = $config['prod']['secret_key']; - $perishableKey = $config['prod']['perishable_key']; - $webhookSecret = $config['prod']['webhook_secret']; - $testSecret = $config['test']['secret_key']; - $testPerishableKey = $config['test']['perishable_key']; - $testWebhookSecret = $config['test']['webhook_secret']; - - $container->setParameter( - 'miracode_stripe.environment', - $env - ); - - $container->setParameter( - 'miracode_stripe.test.secret_key', - $testSecret - ); - $container->setParameter( - 'miracode_stripe.test.perishable_key', - $testPerishableKey - ); - $container->setParameter( - 'miracode_stripe.test.webhook_secret', - $testWebhookSecret - ); - $container->setParameter( 'miracode_stripe.secret_key', - $secret - ); - $container->setParameter( - 'miracode_stripe.perishable_key', - $perishableKey + $config['secret_key'] ); + $container->setParameter( 'miracode_stripe.webhook_secret', - $webhookSecret + $config['webhook_secret'] ); $container->setParameter( @@ -88,8 +58,9 @@ public function load(array $configs, ContainerBuilder $container) ); } if ($this->configureDatabase($config['database'], $container)) { + // If the bundle event listener is to be used. - if (true === $config['use_bundle_subscriber']) { + if($config['use_bundle_subscriber'] === true) { $loader->load('listener.xml'); } } @@ -98,12 +69,12 @@ public function load(array $configs, ContainerBuilder $container) /** * @param array $config + * @param ContainerBuilder $container * * @return bool */ - private function configureDatabase($config, ContainerBuilder $container) - { - if ('orm' == $config['driver']) { + private function configureDatabase($config, ContainerBuilder $container) { + if ($config['driver'] == 'orm') { if (!isset($config['object_manager'])) { $config['object_manager'] = 'doctrine.orm.entity_manager'; } @@ -122,7 +93,7 @@ private function configureDatabase($config, ContainerBuilder $container) $definition->setArguments([ new Reference('miracode_stripe.object_manager'), new Reference('miracode_stripe.model_transformer'), - '%miracode_stripe.model_classes%', + '%miracode_stripe.model_classes%' ]); $definition->setPublic(true); $container->setDefinition( @@ -132,7 +103,7 @@ private function configureDatabase($config, ContainerBuilder $container) return true; } - // TODO: support other drivers + //TODO: support other drivers return false; } diff --git a/Resources/config/services.xml b/Resources/config/services.xml index 612c01c..a0cbd74 100755 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -8,7 +8,7 @@ - + @@ -16,14 +16,7 @@ class="Miracode\StripeBundle\Transformer\AnnotationTransformer"> - - %miracode_stripe.environment% - %miracode_stripe.secret_key% - %miracode_stripe.perishable_key% - %miracode_stripe.test.secret_key% - %miracode_stripe.test.perishable_key% - %miracode_stripe.api_version% - + %miracode_stripe.secret_key% diff --git a/Stripe/StripeClient.php b/Stripe/StripeClient.php index efd1d8c..d41f6b6 100755 --- a/Stripe/StripeClient.php +++ b/Stripe/StripeClient.php @@ -1,78 +1,196 @@ customers->create([ - 'source' => $paymentToken, - 'email' => $customerEmail, + $customer = Customer::create([ + 'source' => $paymentToken, + 'email' => $customerEmail ]); $data = [ - 'customer' => $customer->id, - 'plan' => $planId, + 'customer' => $customer->id, + 'plan' => $planId, ]; if ($couponId) { $data['coupon'] = $couponId; } - $subscription = $this->subscriptions->create($data); + $subscription = Subscription::create($data); return $customer; } @@ -80,107 +198,109 @@ public function subscribeCustomerToPlan($planId, $paymentToken, $customerEmail, /** * Associate an existing Customer object to an existing Plan. * + * @throws HttpException: + * - If the customerId is invalid (the customer does not exists...) + * - If the planId is invalid (the plan does not exists...) + * * @see https://stripe.com/docs/api#create_subscription * * @param string $customerId: The customer ID as defined in your Stripe dashboard - * @param string $planId: The plan ID as defined in your Stripe dashboard - * @param array $parameters: Optional additional parameters, the complete list is available here: https://stripe.com/docs/api#create_subscription + * @param string $planId: The plan ID as defined in your Stripe dashboard + * @param array $parameters: Optional additional parameters, the complete list is available here: https://stripe.com/docs/api#create_subscription * * @return Subscription - * - * @throws HttpException: - * - If the customerId is invalid (the customer does not exists...) - * - If the planId is invalid (the plan does not exists...) */ public function subscribeExistingCustomerToPlan($customerId, $planId, $parameters = []) { $data = [ - 'customer' => $customerId, - 'plan' => $planId, + 'customer' => $customerId, + 'plan' => $planId ]; if (is_array($parameters) && !empty($parameters)) { $data = array_merge($parameters, $data); } - return $this->subscriptions->create($data); + return Subscription::create($data); } /** * Associate an existing Customer object to an existing Plan. * + * @throws HttpException: + * - If the customerId is invalid (the customer does not exists...) + * - If the planId is invalid (the plan does not exists...) + * * @see https://stripe.com/docs/api#create_subscription * * @param string $customerId: The customer ID as defined in your Stripe dashboard - * @param array $items: An Array of Plan items - * @param array $parameters: Optional additional parameters, the complete list is available here: https://stripe.com/docs/api#create_subscription + * @param array $items: An Array of Plan items. + * @param array $parameters: Optional additional parameters, the complete list is available here: https://stripe.com/docs/api#create_subscription * * @return Subscription - * - * @throws HttpException: - * - If the customerId is invalid (the customer does not exists...) - * - If the planId is invalid (the plan does not exists...) */ public function subscribeExistingCustomerToMultiplePlans($customerId, $items = [], $parameters = []) { $data = [ - 'customer' => $customerId, - 'items' => $items, + 'customer' => $customerId, + 'items' => $items ]; if (is_array($parameters) && !empty($parameters)) { $data = array_merge($parameters, $data); } - return $this->subscriptions->create($data); + return Subscription::create($data); } /** + * @param $subscriptionId + * @param $planId + * @param $quantity * @param array $parameters - * * @return SubscriptionItem */ public function createSubscriptionItem($subscriptionId, $planId, $quantity, $parameters = []) { $data = [ - 'subscription' => $subscriptionId, - 'plan' => $planId, - 'quantity' => $quantity, + "subscription" => $subscriptionId, + "plan" => $planId, + "quantity" => $quantity, ]; if (is_array($parameters) && !empty($parameters)) { $data = array_merge($parameters, $data); } - return $this->subscriptionItems->create($data); + return SubscriptionItem::create($data); } /** * Create a new Charge from a payment token, to an optional connected stripe account, with an optional application fee. * + * @throws HttpException: + * - If the payment token is invalid (payment failed) + * * @see https://stripe.com/docs/charges * - * @param int $chargeAmount: The charge amount in cents - * @param string $chargeCurrency: The charge currency to use - * @param string $paymentToken: The payment token returned by the payment form (Stripe.js) + * @param int $chargeAmount: The charge amount in cents + * @param string $chargeCurrency: The charge currency to use + * @param string $paymentToken: The payment token returned by the payment form (Stripe.js) * @param string $stripeAccountId: The connected stripe account ID - * @param int $applicationFee: The fee taken by the platform, in cents - * @param string $description: An optional charge description - * @param array $metadata: An optional array of metadatas + * @param int $applicationFee: The fee taken by the platform, in cents + * @param string $description: An optional charge description + * @param array $metadata: An optional array of metadatas * * @return Charge - * - * @throws HttpException: - * - If the payment token is invalid (payment failed) */ public function createCharge($chargeAmount, $chargeCurrency, $paymentToken, $stripeAccountId = null, $applicationFee = 0, $chargeDescription = '', $chargeMetadata = []) { $chargeOptions = [ - 'amount' => $chargeAmount, - 'currency' => $chargeCurrency, - 'source' => $paymentToken, - 'description' => $chargeDescription, - 'metadata' => $chargeMetadata, + 'amount' => $chargeAmount, + 'currency' => $chargeCurrency, + 'source' => $paymentToken, + 'description' => $chargeDescription, + 'metadata' => $chargeMetadata ]; if ($applicationFee && intval($applicationFee) > 0) { @@ -193,98 +313,98 @@ public function createCharge($chargeAmount, $chargeCurrency, $paymentToken, $str $connectedAccountOptions['stripe_account'] = $stripeAccountId; } - return $this->charges->create($chargeOptions, $connectedAccountOptions); + return Charge::create($chargeOptions, $connectedAccountOptions); } /** * Create a new Destination Charge from a payment token, to a connected stripe account, with an application fee. * + * @throws HttpException: + * - If the payment token is invalid (payment failed) + * * @see https://stripe.com/docs/connect/destination-charges * - * @param int $chargeAmount: The charge amount in cents - * @param string $chargeCurrency: The charge currency to use - * @param string $paymentToken: The payment token returned by the payment form (Stripe.js) - * @param string $stripeAccountId: The connected stripe account ID - * @param int $applicationFee: The fee taken by the platform, in cents + * @param int $chargeAmount: The charge amount in cents + * @param string $chargeCurrency: The charge currency to use + * @param string $paymentToken: The payment token returned by the payment form (Stripe.js) + * @param string $stripeAccountId: The connected stripe account ID + * @param int $applicationFee: The fee taken by the platform, in cents * @param string $chargeDescription: An optional charge description - * @param array $chargeMetadata: An optional array of metadatas + * @param array $chargeMetadata: An optional array of metadatas * * @return Charge - * - * @throws HttpException: - * - If the payment token is invalid (payment failed) */ public function createDestinationCharge($chargeAmount, $chargeCurrency, $paymentToken, $stripeAccountId, $applicationFee, $chargeDescription = '', $chargeMetadata = []) { $chargeOptions = [ - 'amount' => $chargeAmount, - 'currency' => $chargeCurrency, - 'source' => $paymentToken, - 'description' => $chargeDescription, - 'metadata' => $chargeMetadata, - 'destination' => [ + 'amount' => $chargeAmount, + 'currency' => $chargeCurrency, + 'source' => $paymentToken, + 'description' => $chargeDescription, + 'metadata' => $chargeMetadata, + 'destination' => [ 'amount' => $chargeAmount - $applicationFee, - 'account' => $stripeAccountId, - ], + 'account' => $stripeAccountId + ] ]; - return $this->charges->create($chargeOptions); + return Charge::create($chargeOptions); } /** * Create a new Charge from a payment token, to an optional connected stripe account, with an optional application fee. * + * @throws HttpException: + * - If the payment token is invalid (payment failed) + * * @see https://stripe.com/docs/charges#saving-credit-card-details-for-later * * @param string $paymentToken: The payment token returned by the payment form (Stripe.js) - * @param string $email: An optional customer e-mail - * @param array $parameters: Optional additional parameters, the complete list is available here: https://stripe.com/docs/api#create_customer + * @param string $email: An optional customer e-mail + * @param array $parameters: Optional additional parameters, the complete list is available here: https://stripe.com/docs/api#create_customer * * @return Charge - * - * @throws HttpException: - * - If the payment token is invalid (payment failed) */ public function createCustomer($paymentToken, $email = null, $parameters = []) { $data = [ 'source' => $paymentToken, - 'email' => $email, + 'email' => $email ]; if (is_array($parameters) && !empty($parameters)) { $data = array_merge($parameters, $data); } - return $this->customers->create($data); + return Customer::create($data); } /** - * Create a new Charge on an existing Customer object, to an optional connected stripe account, with an optional application fee. + * Create a new Charge on an existing Customer object, to an optional connected stripe account, with an optional application fee + * + * @throws HttpException: + * - If the payment token is invalid (payment failed) * * @see https://stripe.com/docs/charges#saving-credit-card-details-for-later * - * @param int $chargeAmount: The charge amount in cents - * @param string $chargeCurrency: The charge currency to use - * @param string $customerId: The Stripe Customer object ID + * @param int $chargeAmount: The charge amount in cents + * @param string $chargeCurrency: The charge currency to use + * @param string $customerId: The Stripe Customer object ID * @param string $stripeAccountId: The connected stripe account ID - * @param int $applicationFee: The fee taken by the platform, in cents - * @param string $description: An optional charge description - * @param array $metadata: An optional array of metadatas + * @param int $applicationFee: The fee taken by the platform, in cents + * @param string $description: An optional charge description + * @param array $metadata: An optional array of metadatas * * @return Charge - * - * @throws HttpException: - * - If the payment token is invalid (payment failed) */ public function chargeCustomer($chargeAmount, $chargeCurrency, $customerId, $stripeAccountId = null, $applicationFee = 0, $chargeDescription = '', $chargeMetadata = []) { $chargeOptions = [ - 'amount' => $chargeAmount, - 'currency' => $chargeCurrency, - 'customer' => $customerId, - 'description' => $chargeDescription, - 'metadata' => $chargeMetadata, + 'amount' => $chargeAmount, + 'currency' => $chargeCurrency, + 'customer' => $customerId, + 'description' => $chargeDescription, + 'metadata' => $chargeMetadata ]; if ($applicationFee && intval($applicationFee) > 0) { @@ -297,36 +417,36 @@ public function chargeCustomer($chargeAmount, $chargeCurrency, $customerId, $str $connectedAccountOptions['stripe_account'] = $stripeAccountId; } - return $this->charges->create($chargeOptions, $connectedAccountOptions); + return Charge::create($chargeOptions, $connectedAccountOptions); } /** * Create a new Refund on an existing Charge (by its ID). * + * @throws HttpException: + * - If the charge id is invalid (the charge does not exists...) + * - If the charge has already been refunded + * * @see https://stripe.com/docs/connect/direct-charges#issuing-refunds * - * @param string $chargeId: The charge ID - * @param int $refundAmount: The charge amount in cents - * @param array $metadata: optional additional informations about the refund - * @param string $reason: The reason of the refund, either "requested_by_customer", "duplicate" or "fraudulent" - * @param bool $refundApplicationFee: Wether the application_fee should be refunded aswell - * @param bool $reverseTransfer: Wether the transfer should be reversed - * @param string $stripeAccountId: The optional connected stripe account ID on which charge has been made + * @param string $chargeId: The charge ID + * @param int $refundAmount: The charge amount in cents + * @param array $metadata: optional additional informations about the refund + * @param string $reason: The reason of the refund, either "requested_by_customer", "duplicate" or "fraudulent" + * @param bool $refundApplicationFee: Wether the application_fee should be refunded aswell. + * @param bool $reverseTransfer: Wether the transfer should be reversed + * @param string $stripeAccountId: The optional connected stripe account ID on which charge has been made. * * @return Refund - * - * @throws HttpException: - * - If the charge id is invalid (the charge does not exists...) - * - If the charge has already been refunded */ public function refundCharge($chargeId, $refundAmount = null, $metadata = [], $reason = 'requested_by_customer', $refundApplicationFee = true, $reverseTransfer = false, $stripeAccountId = null) { $refundOptions = [ - 'charge' => $chargeId, - 'metadata' => $metadata, - 'reason' => $reason, - 'refund_application_fee' => (bool) $refundApplicationFee, - 'reverse_transfer' => (bool) $reverseTransfer, + 'charge' => $chargeId, + 'metadata' => $metadata, + 'reason' => $reason, + 'refund_application_fee' => (bool) $refundApplicationFee, + 'reverse_transfer' => (bool) $reverseTransfer ]; if ($refundAmount) { @@ -339,17 +459,16 @@ public function refundCharge($chargeId, $refundAmount = null, $metadata = [], $r $connectedAccountOptions['stripe_account'] = $stripeAccountId; } - return $this->refunds->create($refundOptions, $connectedAccountOptions); + return Refund::create($refundOptions, $connectedAccountOptions); } /** - * @param string $name Product Name - * @param string $type 'service' or 'goods' - * @param array $parameters Array of additional parameters to pass to the constructor - * + * @param string $name Product Name + * @param string $type 'service' or 'goods' + * @param array $parameters Array of additional parameters to pass to the constructor * @return Product */ - public function createProduct($name, $type, $parameters = []) + public function createProduct($name, $type, $parameters =[] ) { $data = [ 'name' => $name, @@ -360,53 +479,54 @@ public function createProduct($name, $type, $parameters = []) $data = array_merge($parameters, $data); } - return $this->products::create($data); + return Product::create($data); } /** * @param string $productId * @param string $interval - * @param null $currency Currency to billin , defaults to 'eur' - * @param array $parameters - * + * @param null $currency Currency to billin , defaults to 'eur' + * @param array $parameters * @return Plan */ - public function createPlan($productId, $interval, $currency = null, $parameters = []) + public function createPlan($productId, $interval, $currency = null, $parameters = [] ) { - if (null === $currency) { + + if($currency === null){ $currency = 'eur'; } $data = [ 'product' => $productId, 'interval' => $interval, - 'currency' => $currency, + 'currency' =>$currency, ]; if (is_array($parameters) && !empty($parameters)) { $data = array_merge($parameters, $data); } - return $this->plans->create($data); + return Plan::create($data); + } /** - * @param string $id - * @param string $duration - * @param bool $isPercentage True = percentage_type deduction, false = amount_type - * @param int|float $discount The percentage discount, or amount discount - * @param array $parameters Additional parameters to pass to the constructor - * + * @param string $id + * @param string $duration + * @param bool $isPercentage True = percentage_type deduction, false = amount_type + * @param int|float $discount The percentage discount, or amount discount + * @param array $parameters Additional parameters to pass to the constructor * @return Coupon */ public function createCoupon($id, $duration, $isPercentage, $discount, $parameters = []) { + $data = [ - 'id' => $id, - 'duration' => $duration, + "id" => $id, + "duration" => $duration, ]; - if ($isPercentage) { + if($isPercentage){ $data['percent_off'] = $discount; } else { $data['amount_off'] = $discount; @@ -416,6 +536,6 @@ public function createCoupon($id, $duration, $isPercentage, $discount, $paramete $data = array_merge($parameters, $data); } - return $this->coupons->create($data); + return Coupon::create($data); } } diff --git a/Stripe/StripeObjectType.php b/Stripe/StripeObjectType.php index c1eda83..1481314 100755 --- a/Stripe/StripeObjectType.php +++ b/Stripe/StripeObjectType.php @@ -4,15 +4,18 @@ class StripeObjectType { - public const CARD = 'card'; - public const CHARGE = 'charge'; - public const COUPON = 'coupon'; - public const CUSTOMER = 'customer'; - public const DISCOUNT = 'discount'; - public const EVENT = 'event'; - public const INVOICE = 'invoice'; - public const PLAN = 'plan'; - public const REFUND = 'refund'; - public const SUBSCRIPTION = 'subscription'; - public const COLLECTION = 'list'; + /** + * Stripe object types + */ + const CARD = 'card'; + const CHARGE = 'charge'; + const COUPON = 'coupon'; + const CUSTOMER = 'customer'; + const DISCOUNT = 'discount'; + const EVENT = 'event'; + const INVOICE = 'invoice'; + const PLAN = 'plan'; + const REFUND = 'refund'; + const SUBSCRIPTION = 'subscription'; + const COLLECTION = 'list'; } diff --git a/composer.json b/composer.json index 6331bb5..b480d3b 100755 --- a/composer.json +++ b/composer.json @@ -18,16 +18,16 @@ } ], "require": { - "php" : ">=8.0", - "symfony/framework-bundle" : ">=6.3", - "symfony/config" : ">=6.3", - "stripe/stripe-php" : ">=12.0", - "doctrine/common" : ">=3.2" + "php" : ">=5.4.0", + "symfony/framework-bundle" : ">=2.4", + "symfony/config" : ">=2.3", + "stripe/stripe-php" : ">=3.0", + "doctrine/common" : ">=2.2" }, "require-dev": { - "doctrine/orm" : ">=2.10", + "doctrine/orm" : ">=2.2", "symfony/yaml" : "^2.8 || ^3.0 || ^4.0", - "phpunit/phpunit" : "~4.8|~5.0|~6.0" + "phpunit/phpunit" : "~4.8|~5.0" }, "suggest": { "doctrine/orm" : "If you want to save stripe data in database" From 5ba2b7586e01c9fbf3bde53fdcaa6dcdf104d112 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Tue, 6 Feb 2024 15:24:33 +0000 Subject: [PATCH 49/61] Add Products and Prices. Deprecate Plans --- DependencyInjection/Configuration.php | 1 + Manager/Doctrine/DoctrineORMModelManager.php | 60 +-- Model/AbstractPriceModel.php | 510 ++++++++++++++++++ Model/AbstractProductModel.php | 314 ++++++----- Model/StripeModel.php | 14 +- .../doctrine/model/AbstractPriceModel.orm.xml | 30 ++ .../model/AbstractProductModel.orm.xml | 25 +- Stripe/StripeClient.php | 9 +- Transformer/AnnotationTransformer.php | 16 +- composer.json | 2 +- 10 files changed, 763 insertions(+), 218 deletions(-) create mode 100755 Model/AbstractPriceModel.php create mode 100755 Resources/config/doctrine/model/AbstractPriceModel.orm.xml diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 7288e4c..91b3be2 100755 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -65,6 +65,7 @@ public function getConfigTreeBuilder(): TreeBuilder ->scalarNode('invoice')->cannotBeEmpty()->end() ->scalarNode('payout')->cannotBeEmpty()->end() ->scalarNode('product')->cannotBeEmpty()->end() + ->scalarNode('price')->cannotBeEmpty()->end() ->scalarNode('plan')->cannotBeEmpty()->end() ->scalarNode('refund')->cannotBeEmpty()->end() ->scalarNode('subscription')->cannotBeEmpty()->end() diff --git a/Manager/Doctrine/DoctrineORMModelManager.php b/Manager/Doctrine/DoctrineORMModelManager.php index f7b5342..a4ca9f6 100755 --- a/Manager/Doctrine/DoctrineORMModelManager.php +++ b/Manager/Doctrine/DoctrineORMModelManager.php @@ -5,13 +5,10 @@ use Doctrine\Common\Persistence\ObjectManager; use Doctrine\ORM\EntityManagerInterface; use Miracode\StripeBundle\Manager\ModelManagerInterface; -use Miracode\StripeBundle\Model\AbstractCustomerModel; -use Miracode\StripeBundle\Model\AbstractProductModel; use Miracode\StripeBundle\Model\SafeDeleteModelInterface; use Miracode\StripeBundle\Model\StripeModelInterface; use Miracode\StripeBundle\StripeException; use Miracode\StripeBundle\Transformer\TransformerInterface; -use Stripe\Customer; use Stripe\StripeObject; class DoctrineORMModelManager implements ModelManagerInterface @@ -33,8 +30,7 @@ class DoctrineORMModelManager implements ModelManagerInterface /** * DoctrineORMModelManager constructor. - * @param EntityManagerInterface $objectManager - * @param TransformerInterface $transformer + * * @param array $modelClasses */ public function __construct( @@ -48,9 +44,7 @@ public function __construct( } /** - * Is stripe object supported by model manager - * - * @param StripeObject $object + * Is stripe object supported by model manager. * * @return bool */ @@ -60,9 +54,7 @@ public function support(StripeObject $object) } /** - * Retrieve model by stripe object data - * - * @param StripeObject $object + * Retrieve model by stripe object data. * * @return StripeModelInterface|object|null */ @@ -72,15 +64,16 @@ public function retrieve(StripeObject $object) $modelClass = $this->modelClass($object); return $this->objectManager->getRepository($modelClass)->findOneBy([ - 'id' => $object->id + 'id' => $object->id, ]); } /** - * Retrieve model by stripe ID and stripe object type + * Retrieve model by stripe ID and stripe object type. * * @param string $id * @param string $objectType + * * @return StripeModelInterface|null */ public function retrieveById($id, $objectType) @@ -92,9 +85,8 @@ public function retrieveById($id, $objectType) } /** - * Save stripe object in database + * Save stripe object in database. * - * @param StripeObject $object * @param bool $flush * * @return StripeModelInterface @@ -106,6 +98,7 @@ public function save(StripeObject $object, $flush = false) $model = $this->createModel($object); $this->objectManager->persist($model); } + $this->modelTransformer->transform($object, $model); if ($flush) { $this->objectManager->flush(); @@ -116,9 +109,8 @@ public function save(StripeObject $object, $flush = false) /** * Remove model from database by stripe object data - * Return model object that was removed or NULL if model does not exists + * Return model object that was removed or NULL if model does not exists. * - * @param StripeObject $object * @param bool $flush * * @return StripeModelInterface|null @@ -142,22 +134,17 @@ public function remove(StripeObject $object, $flush = false) } /** - * Get stripe object type - * - * @param StripeObject $object + * Get stripe object type. * * @return string + * * @throws StripeException */ protected function getObjectType(StripeObject $object) { if (empty($object->object)) { if (isset($object->deleted) && isset($object->id)) { - throw new StripeException(sprintf( - 'Couldn\'t detect stripe object type. ' - . 'Stripe object with ID `%s` has been already deleted.', - $object->id - )); + throw new StripeException(sprintf('Couldn\'t detect stripe object type. Stripe object with ID `%s` has been already deleted.', $object->id)); } throw new StripeException('Couldn\'t detect stripe object type.'); } @@ -166,28 +153,19 @@ protected function getObjectType(StripeObject $object) } /** - * Check object support - * - * @param \Stripe\StripeObject $object + * Check object support. * * @throws \Miracode\StripeBundle\StripeException */ protected function checkSupport(StripeObject $object) { if (!$this->support($object)) { - throw new StripeException(sprintf( - 'Stripe object `%1$s` does not support. ' - . 'Please specify model class for object type `%1$s` ' - . 'in miracode_stripe.database.model.%1$s', - $this->getObjectType($object) - )); + throw new StripeException(sprintf('Stripe object `%1$s` does not support. Please specify model class for object type `%1$s` in miracode_stripe.database.model.%1$s', $this->getObjectType($object))); } } /** - * Get model class name for specified stripe object - * - * @param StripeObject $object + * Get model class name for specified stripe object. * * @return string */ @@ -197,23 +175,19 @@ protected function modelClass(StripeObject $object) } /** - * Create new model object - * - * @param StripeObject $object + * Create new model object. * * @return StripeModelInterface */ protected function createModel(StripeObject $object) { - $className = $this->modelClass($object); $class = new $className(); - if($object->id){ + if ($object->id) { $class->setId($object->id); } return $class; - } } diff --git a/Model/AbstractPriceModel.php b/Model/AbstractPriceModel.php new file mode 100755 index 0000000..11e71bc --- /dev/null +++ b/Model/AbstractPriceModel.php @@ -0,0 +1,510 @@ +active; + } + + /** + * @param bool $active + * @return AbstractPriceModel + */ + public function setActive(bool $active): AbstractPriceModel + { + $this->active = $active; + + return $this; + } + + /** + * @return string + */ + public function getCurrency(): string + { + return $this->currency; + } + + /** + * @param string $currency + * @return AbstractPriceModel + */ + public function setCurrency(string $currency): AbstractPriceModel + { + $this->currency = $currency; + + return $this; + } + + /** + * @return array + */ + public function getMetadata(): array + { + return $this->metadata; + } + + /** + * @param array $metadata + * @return AbstractPriceModel + */ + public function setMetadata(array $metadata): AbstractPriceModel + { + $this->metadata = $metadata; + + return $this; + } + + /** + * @return string|null + */ + public function getNickname(): ?string + { + return $this->nickname; + } + + /** + * @param string|null $nickname + * @return AbstractPriceModel + */ + public function setNickname(?string $nickname): AbstractPriceModel + { + $this->nickname = $nickname; + + return $this; + } + + /** + * @return string + */ + public function getProduct(): string + { + return $this->product; + } + + /** + * @param string $product + * @return AbstractPriceModel + */ + public function setProduct(string $product): AbstractPriceModel + { + $this->product = $product; + + return $this; + } + + /** + * @return array|null + */ + public function getRecurring(): ?array + { + return $this->recurring; + } + + /** + * @param array|null $recurring + * @return AbstractPriceModel + */ + public function setRecurring(?array $recurring): AbstractPriceModel + { + $this->recurring = $recurring; + + return $this; + } + + /** + * @return string + */ + public function getType(): string + { + return $this->type; + } + + /** + * @param string $type + * @return AbstractPriceModel + */ + public function setType(string $type): AbstractPriceModel + { + $this->type = $type; + + return $this; + } + + /** + * @return int|null + */ + public function getUnitAmount(): ?int + { + return $this->unitAmount; + } + + /** + * @param int|null $unitAmount + * @return AbstractPriceModel + */ + public function setUnitAmount(?int $unitAmount): AbstractPriceModel + { + $this->unitAmount = $unitAmount; + + return $this; + } + + /** + * @return string + */ + public function getObject(): string + { + return $this->object; + } + + /** + * @param string $object + * @return AbstractPriceModel + */ + public function setObject(string $object): AbstractPriceModel + { + $this->object = $object; + + return $this; + } + + /** + * @return string + */ + public function getBillingScheme(): string + { + return $this->billingScheme; + } + + /** + * @param string $billingScheme + * @return AbstractPriceModel + */ + public function setBillingScheme(string $billingScheme): AbstractPriceModel + { + $this->billingScheme = $billingScheme; + + return $this; + } + + /** + * @return int + */ + public function getCreated(): int + { + return $this->created; + } + + /** + * @param int $created + * @return AbstractPriceModel + */ + public function setCreated(int $created): AbstractPriceModel + { + $this->created = $created; + + return $this; + } + + /** + * @return array|null + */ + public function getCurrencyOptions(): ?array + { + return $this->currencyOptions; + } + + /** + * @param array|null $currencyOptions + * @return AbstractPriceModel + */ + public function setCurrencyOptions(?array $currencyOptions): AbstractPriceModel + { + $this->currencyOptions = $currencyOptions; + + return $this; + } + + /** + * @return array|null + */ + public function getCustomUnitAmount(): ?array + { + return $this->customUnitAmount; + } + + /** + * @param array|null $customUnitAmount + * @return AbstractPriceModel + */ + public function setCustomUnitAmount(?array $customUnitAmount): AbstractPriceModel + { + $this->customUnitAmount = $customUnitAmount; + + return $this; + } + + /** + * @return bool + */ + public function isLivemode(): bool + { + return $this->livemode; + } + + /** + * @param bool $livemode + * @return AbstractPriceModel + */ + public function setLivemode(bool $livemode): AbstractPriceModel + { + $this->livemode = $livemode; + + return $this; + } + + /** + * @return string|null + */ + public function getLookupKey(): ?string + { + return $this->lookupKey; + } + + /** + * @param string|null $lookupKey + * @return AbstractPriceModel + */ + public function setLookupKey(?string $lookupKey): AbstractPriceModel + { + $this->lookupKey = $lookupKey; + + return $this; + } + + /** + * @return string|null + */ + public function getTaxBehaviour(): ?string + { + return $this->taxBehaviour; + } + + /** + * @param string|null $taxBehaviour + * @return AbstractPriceModel + */ + public function setTaxBehaviour(?string $taxBehaviour): AbstractPriceModel + { + $this->taxBehaviour = $taxBehaviour; + + return $this; + } + + /** + * @return array|null + */ + public function getTiers(): ?array + { + return $this->tiers; + } + + /** + * @param array|null $tiers + * @return AbstractPriceModel + */ + public function setTiers(?array $tiers): AbstractPriceModel + { + $this->tiers = $tiers; + + return $this; + } + + /** + * @return string|null + */ + public function getTiersMode(): ?string + { + return $this->tiersMode; + } + + /** + * @param string|null $tiersMode + * @return AbstractPriceModel + */ + public function setTiersMode(?string $tiersMode): AbstractPriceModel + { + $this->tiersMode = $tiersMode; + + return $this; + } + + /** + * @return array|null + */ + public function getTransformQuality(): ?array + { + return $this->transformQuality; + } + + /** + * @param array|null $transformQuality + * @return AbstractPriceModel + */ + public function setTransformQuality(?array $transformQuality): AbstractPriceModel + { + $this->transformQuality = $transformQuality; + + return $this; + } + + /** + * @return string|null + */ + public function getUnitAmountDecimal(): ?string + { + return $this->unitAmountDecimal; + } + + /** + * @param string|null $unitAmountDecimal + * @return AbstractPriceModel + */ + public function setUnitAmountDecimal(?string $unitAmountDecimal): AbstractPriceModel + { + $this->unitAmountDecimal = $unitAmountDecimal; + + return $this; + } +} diff --git a/Model/AbstractProductModel.php b/Model/AbstractProductModel.php index 3393f9a..9368e08 100755 --- a/Model/AbstractProductModel.php +++ b/Model/AbstractProductModel.php @@ -6,373 +6,413 @@ abstract class AbstractProductModel extends StripeModel { + /** * @StripeObjectParam - * - * @var string */ - protected $object; + protected bool $active; /** - * @StripeObjectParam - * - * @var boolean + * @StripeObjectParam(name="default_price") */ - protected $active; + protected ?string $defaultPrice = null; /** * @StripeObjectParam - * - * @var array */ - protected $attributes; + protected ?string $description = null; /** * @StripeObjectParam - * - * @var int */ - protected $created; + protected array $metadata; /** * @StripeObjectParam - * - * @var array */ - protected $deactivateOn; + protected string $name; /** * @StripeObjectParam - * - * @var string */ - protected $description; + protected string $object; /** * @StripeObjectParam - * - * @var array */ - protected $images; + protected int $created; /** * @StripeObjectParam - * - * @var boolean */ - protected $livemode; + protected array $features; /** * @StripeObjectParam - * - * @var array */ - protected $metadata; + protected array $images; /** * @StripeObjectParam - * - * @var string */ - protected $name; + protected bool $livemode; /** - * @StripeObjectParam - * - * @var array + * @StripeObjectParam(name="package_dimensions") */ - protected $packageDimensions; + protected ?array $packageDimensions = null; /** * @StripeObjectParam - * - * @var boolean */ - protected $shippable; + protected ?bool $shippable = null; /** - * @StripeObjectParam - * - * @var string + * @StripeObjectParam(name="statement_descriptor") */ - protected $statementDescriptor; + protected ?string $statementDescriptor = null; /** - * @StripeObjectParam - * - * @var string + * @StripeObjectParam(name="tax_code") */ - protected $type; + protected ?string $taxCode = null; + + /** + * @StripeObjectParam(name="unit_label") + */ + protected ?string $unitLabel = null; /** * @StripeObjectParam - * - * @var int */ - protected $updated; + protected ?int $updated = null; /** * @StripeObjectParam - * - * @var string */ - protected $url; + protected ?string $url = null; /** - * @return string + * @return bool */ - public function getObject() + public function isActive(): bool { - return $this->object; + return $this->active; } /** - * @param string $object + * @param bool $active + * @return AbstractProductModel */ - public function setObject($object) + public function setActive(bool $active): AbstractProductModel { - $this->object = $object; + $this->active = $active; + + return $this; } /** - * @return bool + * @return string|null */ - public function isActive() + public function getDefaultPrice(): ?string { - return $this->active; + return $this->defaultPrice; } /** - * @param bool $active + * @param string|null $defaultPrice + * @return AbstractProductModel */ - public function setActive($active) + public function setDefaultPrice(?string $defaultPrice): AbstractProductModel { - $this->active = $active; + $this->defaultPrice = $defaultPrice; + + return $this; } /** - * @return array + * @return string|null */ - public function getAttributes() + public function getDescription(): ?string { - return $this->attributes; + return $this->description; } /** - * @param array $attributes + * @param string|null $description + * @return AbstractProductModel */ - public function setAttributes($attributes) + public function setDescription(?string $description): AbstractProductModel { - $this->attributes = $attributes; + $this->description = $description; + + return $this; } /** - * @return int + * @return array */ - public function getCreated() + public function getMetadata(): array { - return $this->created; + return $this->metadata; } /** - * @param int $created + * @param array $metadata + * @return AbstractProductModel */ - public function setCreated($created) + public function setMetadata(array $metadata): AbstractProductModel { - $this->created = $created; + $this->metadata = $metadata; + + return $this; } /** - * @return array + * @return string */ - public function getDeactivateOn() + public function getName(): string { - return $this->deactivateOn; + return $this->name; } /** - * @param array $deactivateOn + * @param string $name + * @return AbstractProductModel */ - public function setDeactivateOn($deactivateOn) + public function setName(string $name): AbstractProductModel { - $this->deactivateOn = $deactivateOn; + $this->name = $name; + + return $this; } /** * @return string */ - public function getDescription() + public function getObject(): string { - return $this->description; + return $this->object; } /** - * @param string $description + * @param string $object + * @return AbstractProductModel */ - public function setDescription($description) + public function setObject(string $object): AbstractProductModel { - $this->description = $description; + $this->object = $object; + + return $this; } /** - * @return array + * @return int */ - public function getImages() + public function getCreated(): int { - return $this->images; + return $this->created; } /** - * @param array $images + * @param int $created + * @return AbstractProductModel */ - public function setImages($images) + public function setCreated(int $created): AbstractProductModel { - $this->images = $images; + $this->created = $created; + + return $this; } /** - * @return bool + * @return array */ - public function isLivemode() + public function getFeatures(): array { - return $this->livemode; + return $this->features; } /** - * @param bool $livemode + * @param array $features + * @return AbstractProductModel */ - public function setLivemode($livemode) + public function setFeatures(array $features): AbstractProductModel { - $this->livemode = $livemode; + $this->features = $features; + + return $this; } /** * @return array */ - public function getMetadata() + public function getImages(): array { - return $this->metadata; + return $this->images; } /** - * @param array $metadata + * @param array $images + * @return AbstractProductModel */ - public function setMetadata($metadata) + public function setImages(array $images): AbstractProductModel { - $this->metadata = $metadata; + $this->images = $images; + + return $this; } /** - * @return string + * @return bool */ - public function getName() + public function isLivemode(): bool { - return $this->name; + return $this->livemode; } /** - * @param string $name + * @param bool $livemode + * @return AbstractProductModel */ - public function setName($name) + public function setLivemode(bool $livemode): AbstractProductModel { - $this->name = $name; + $this->livemode = $livemode; + + return $this; } /** - * @return array + * @return array|null */ - public function getPackageDimensions() + public function getPackageDimensions(): ?array { return $this->packageDimensions; } /** - * @param array $packageDimensions + * @param array|null $packageDimensions + * @return AbstractProductModel */ - public function setPackageDimensions($packageDimensions) + public function setPackageDimensions(?array $packageDimensions): AbstractProductModel { $this->packageDimensions = $packageDimensions; + + return $this; } /** - * @return bool + * @return bool|null */ - public function isShippable() + public function getShippable(): ?bool { return $this->shippable; } /** - * @param bool $shippable + * @param bool|null $shippable + * @return AbstractProductModel */ - public function setShippable($shippable) + public function setShippable(?bool $shippable): AbstractProductModel { $this->shippable = $shippable; + + return $this; } /** - * @return string + * @return string|null */ - public function getStatementDescriptor() + public function getStatementDescriptor(): ?string { return $this->statementDescriptor; } /** - * @param string $statementDescriptor + * @param string|null $statementDescriptor + * @return AbstractProductModel */ - public function setStatementDescriptor($statementDescriptor) + public function setStatementDescriptor(?string $statementDescriptor): AbstractProductModel { $this->statementDescriptor = $statementDescriptor; + + return $this; } /** - * @return string + * @return string|null */ - public function getType() + public function getTaxCode(): ?string { - return $this->type; + return $this->taxCode; } /** - * @param string $type + * @param string|null $taxCode + * @return AbstractProductModel */ - public function setType($type) + public function setTaxCode(?string $taxCode): AbstractProductModel { - $this->type = $type; + $this->taxCode = $taxCode; + + return $this; } /** - * @return int + * @return string|null */ - public function getUpdated() + public function getUnitLabel(): ?string + { + return $this->unitLabel; + } + + /** + * @param string|null $unitLabel + * @return AbstractProductModel + */ + public function setUnitLabel(?string $unitLabel): AbstractProductModel + { + $this->unitLabel = $unitLabel; + + return $this; + } + + /** + * @return int|null + */ + public function getUpdated(): ?int { return $this->updated; } /** - * @param int $updated + * @param int|null $updated + * @return AbstractProductModel */ - public function setUpdated($updated) + public function setUpdated(?int $updated): AbstractProductModel { $this->updated = $updated; + + return $this; } /** - * @return string + * @return string|null */ - public function getUrl() + public function getUrl(): ?string { return $this->url; } /** - * @param string $url + * @param string|null $url + * @return AbstractProductModel */ - public function setUrl($url) + public function setUrl(?string $url): AbstractProductModel { $this->url = $url; - } + return $this; + } } diff --git a/Model/StripeModel.php b/Model/StripeModel.php index af1f692..69de487 100755 --- a/Model/StripeModel.php +++ b/Model/StripeModel.php @@ -8,27 +8,21 @@ class StripeModel implements StripeModelInterface { /** * @StripeObjectParam(name="id") - * - * @var string */ - protected $id; + protected string $id; /** - * Retrieve stripe object ID - * - * @return string + * Retrieve stripe object ID. */ - public function getId() + public function getId(): string { return $this->id; } /** - * @param string $id - * * @return $this */ - public function setId($id) + public function setId(string $id): static { $this->id = $id; diff --git a/Resources/config/doctrine/model/AbstractPriceModel.orm.xml b/Resources/config/doctrine/model/AbstractPriceModel.orm.xml new file mode 100755 index 0000000..17bf683 --- /dev/null +++ b/Resources/config/doctrine/model/AbstractPriceModel.orm.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Resources/config/doctrine/model/AbstractProductModel.orm.xml b/Resources/config/doctrine/model/AbstractProductModel.orm.xml index 6829cb9..1f8da89 100755 --- a/Resources/config/doctrine/model/AbstractProductModel.orm.xml +++ b/Resources/config/doctrine/model/AbstractProductModel.orm.xml @@ -4,23 +4,24 @@ xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> - - + - - - - - + + + + + + + - + - - - - + + + + \ No newline at end of file diff --git a/Stripe/StripeClient.php b/Stripe/StripeClient.php index d41f6b6..582b5b9 100755 --- a/Stripe/StripeClient.php +++ b/Stripe/StripeClient.php @@ -1,12 +1,4 @@ getProperties(); + foreach ($props as $prop) { /** @var StripeObjectParam $stripeObjectParam */ $stripeObjectParam = $annotationReader->getPropertyAnnotation( $prop, "Miracode\StripeBundle\Annotation\StripeObjectParam" ); + if (!$stripeObjectParam) { continue; } if (!$name = $stripeObjectParam->name) { $name = strtolower($prop->getName()); } + if (!isset($stripeObject[$name])) { continue; } @@ -46,10 +46,10 @@ public function transform( $value = $value[$path]; } } else { - if (isset($value->object) && - $value->object == StripeObjectType::COLLECTION + if (isset($value->object) + && StripeObjectType::COLLECTION == $value->object ) { - $value = array_map(function(StripeObject $obj) { + $value = array_map(function (StripeObject $obj) { return $obj->toArray(true); }, $value->data); } else { @@ -58,7 +58,9 @@ public function transform( } } - $setter = 'set' . ucfirst($prop->getName()); + dump($prop->getName()); + dump($value); + $setter = 'set'.ucfirst($prop->getName()); call_user_func([$model, $setter], $value); } } diff --git a/composer.json b/composer.json index b480d3b..cf7d4d4 100755 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ } ], "require": { - "php" : ">=5.4.0", + "php" : ">=7.2", "symfony/framework-bundle" : ">=2.4", "symfony/config" : ">=2.3", "stripe/stripe-php" : ">=3.0", From f6eea538425854bce009fdd0d4e15286b3c0b035 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Wed, 7 Feb 2024 10:32:39 +0000 Subject: [PATCH 50/61] Add price and product --- Event/StripeEvent.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Event/StripeEvent.php b/Event/StripeEvent.php index 977d6a1..015be03 100755 --- a/Event/StripeEvent.php +++ b/Event/StripeEvent.php @@ -43,6 +43,12 @@ class StripeEvent extends Event public const INVOICE_UPCOMING = 'stripe.invoice.upcoming'; public const INVOICE_UPDATED = 'stripe.invoice.updated'; public const INVOICE_VOIDED = 'stripe.invoice.voided'; + public const PRODUCT_CREATED = 'stripe.product.created'; + public const PRODUCT_DELETED = 'stripe.product.deleted'; + public const PRODUCT_UPDATED = 'stripe.product.updated'; + public const PRICE_CREATED = 'stripe.price.created'; + public const PRICE_DELETED = 'stripe.price.deleted'; + public const PRICE_UPDATED = 'stripe.price.updated'; public const PLAN_CREATED = 'stripe.plan.created'; public const PLAN_DELETED = 'stripe.plan.deleted'; public const PLAN_UPDATED = 'stripe.plan.updated'; From c9d50ee41cbbea8291f1ad76c97c926e3a098a58 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Wed, 7 Feb 2024 10:35:14 +0000 Subject: [PATCH 51/61] Subscribe to Price and Product updates --- EventListener/StripeEventSubscriber.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/EventListener/StripeEventSubscriber.php b/EventListener/StripeEventSubscriber.php index 9c3abcf..be70ca0 100755 --- a/EventListener/StripeEventSubscriber.php +++ b/EventListener/StripeEventSubscriber.php @@ -53,12 +53,16 @@ public static function getSubscribedEvents() StripeEvent::INVOICE_PAYMENT_SUCCEEDED => 'onStripeEvent', StripeEvent::INVOICE_SENT => 'onStripeEvent', StripeEvent::INVOICE_UPDATED => 'onStripeEvent', + StripeEvent::PRODUCT_CREATED => 'onStripeEvent', + StripeEvent::PRODUCT_UPDATED => 'onStripeEvent', + StripeEvent::PRICE_CREATED => 'onStripeEvent', + StripeEvent::PRICE_UPDATED => 'onStripeEvent', + StripeEvent::PLAN_UPDATED => 'onStripeEvent', StripeEvent::PLAN_CREATED => 'onStripeEvent', StripeEvent::PLAN_UPDATED => 'onStripeEvent', StripeEvent::SOURCE_CANCELED => 'onStripeEvent', StripeEvent::SOURCE_CHARGEABLE => 'onStripeEvent', StripeEvent::SOURCE_FAILED => 'onStripeEvent', - StripeEvent::COUPON_DELETED => 'onStripeDeleteEvent', StripeEvent::TAX_RATE_CREATED => 'onStripeEvent', StripeEvent::TAX_RATE_UPDATED => 'onStripeEvent', From 297dfbf12aad062c4f652466002f257328544aaa Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Wed, 7 Feb 2024 10:39:08 +0000 Subject: [PATCH 52/61] Update StripeEventSubscriber.php --- EventListener/StripeEventSubscriber.php | 1 - 1 file changed, 1 deletion(-) diff --git a/EventListener/StripeEventSubscriber.php b/EventListener/StripeEventSubscriber.php index be70ca0..b8cd385 100755 --- a/EventListener/StripeEventSubscriber.php +++ b/EventListener/StripeEventSubscriber.php @@ -57,7 +57,6 @@ public static function getSubscribedEvents() StripeEvent::PRODUCT_UPDATED => 'onStripeEvent', StripeEvent::PRICE_CREATED => 'onStripeEvent', StripeEvent::PRICE_UPDATED => 'onStripeEvent', - StripeEvent::PLAN_UPDATED => 'onStripeEvent', StripeEvent::PLAN_CREATED => 'onStripeEvent', StripeEvent::PLAN_UPDATED => 'onStripeEvent', StripeEvent::SOURCE_CANCELED => 'onStripeEvent', From 4a34669053f2a8a349229c38a5523acb7d02bd72 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Wed, 7 Feb 2024 10:45:57 +0000 Subject: [PATCH 53/61] Update AnnotationTransformer.php --- Transformer/AnnotationTransformer.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/Transformer/AnnotationTransformer.php b/Transformer/AnnotationTransformer.php index 2e050cb..5f86345 100755 --- a/Transformer/AnnotationTransformer.php +++ b/Transformer/AnnotationTransformer.php @@ -58,8 +58,6 @@ public function transform( } } - dump($prop->getName()); - dump($value); $setter = 'set'.ucfirst($prop->getName()); call_user_func([$model, $setter], $value); } From 9a49ceed4c97777bf3251b3a1c77bc36a33a362c Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Mon, 1 Jul 2024 14:18:21 +0100 Subject: [PATCH 54/61] Update StripeEvent.php --- Event/StripeEvent.php | 1 + 1 file changed, 1 insertion(+) diff --git a/Event/StripeEvent.php b/Event/StripeEvent.php index 015be03..c4d5ca7 100755 --- a/Event/StripeEvent.php +++ b/Event/StripeEvent.php @@ -14,6 +14,7 @@ class StripeEvent extends Event public const CHARGE_REFUNDED = 'stripe.charge.refunded'; public const CHARGE_SUCCEEDED = 'stripe.charge.succeeded'; public const CHARGE_UPDATED = 'stripe.charge.updated'; + public const CHARGE_DISPUTE_CLOSED = 'charge.dispute.closed'; public const COUPON_CREATED = 'stripe.coupon.created'; public const COUPON_DELETED = 'stripe.coupon.deleted'; public const COUPON_UPDATED = 'stripe.coupon.updated'; From 9b63d33a58ab3b3f2e4ae8852f6ddc1a444869c5 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Mon, 1 Jul 2024 14:20:22 +0100 Subject: [PATCH 55/61] Update StripeEvent.php --- Event/StripeEvent.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Event/StripeEvent.php b/Event/StripeEvent.php index c4d5ca7..244b509 100755 --- a/Event/StripeEvent.php +++ b/Event/StripeEvent.php @@ -14,6 +14,8 @@ class StripeEvent extends Event public const CHARGE_REFUNDED = 'stripe.charge.refunded'; public const CHARGE_SUCCEEDED = 'stripe.charge.succeeded'; public const CHARGE_UPDATED = 'stripe.charge.updated'; + public const CHARGE_DISPUTE_OPENED = 'charge.dispute.opened'; + public const CHARGE_DISPUTE_FUNDS_WITHDRAWN = 'charge.dispute.funds_withdrawn'; public const CHARGE_DISPUTE_CLOSED = 'charge.dispute.closed'; public const COUPON_CREATED = 'stripe.coupon.created'; public const COUPON_DELETED = 'stripe.coupon.deleted'; From bc18eecd030c25c922e549a8e581237a749967c6 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Mon, 1 Jul 2024 14:21:29 +0100 Subject: [PATCH 56/61] Update StripeEvent.php --- Event/StripeEvent.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Event/StripeEvent.php b/Event/StripeEvent.php index 244b509..dc9adc4 100755 --- a/Event/StripeEvent.php +++ b/Event/StripeEvent.php @@ -14,9 +14,9 @@ class StripeEvent extends Event public const CHARGE_REFUNDED = 'stripe.charge.refunded'; public const CHARGE_SUCCEEDED = 'stripe.charge.succeeded'; public const CHARGE_UPDATED = 'stripe.charge.updated'; - public const CHARGE_DISPUTE_OPENED = 'charge.dispute.opened'; - public const CHARGE_DISPUTE_FUNDS_WITHDRAWN = 'charge.dispute.funds_withdrawn'; - public const CHARGE_DISPUTE_CLOSED = 'charge.dispute.closed'; + public const CHARGE_DISPUTE_OPENED = 'stripe.charge.dispute.opened'; + public const CHARGE_DISPUTE_FUNDS_WITHDRAWN = 'stripe.charge.dispute.funds_withdrawn'; + public const CHARGE_DISPUTE_CLOSED = 'stripe.charge.dispute.closed'; public const COUPON_CREATED = 'stripe.coupon.created'; public const COUPON_DELETED = 'stripe.coupon.deleted'; public const COUPON_UPDATED = 'stripe.coupon.updated'; From 351aa6baba42e7be94a4126d30e46f9ecc75a26a Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Thu, 8 Aug 2024 11:04:51 +0100 Subject: [PATCH 57/61] Add Credit note events. --- Event/StripeEvent.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Event/StripeEvent.php b/Event/StripeEvent.php index dc9adc4..0ffe919 100755 --- a/Event/StripeEvent.php +++ b/Event/StripeEvent.php @@ -20,6 +20,9 @@ class StripeEvent extends Event public const COUPON_CREATED = 'stripe.coupon.created'; public const COUPON_DELETED = 'stripe.coupon.deleted'; public const COUPON_UPDATED = 'stripe.coupon.updated'; + public const CREDIT_NOTE_CREATED = 'stripe.credit_note.created'; + public const CREDIT_NOTE_UPDATED = 'stripe.credit_note.updated'; + public const CREDIT_NOTE_VOIDED = 'stripe.credit_note.voided'; public const CUSTOMER_CREATED = 'stripe.customer.created'; public const CUSTOMER_DELETED = 'stripe.customer.deleted'; public const CUSTOMER_UPDATED = 'stripe.customer.updated'; From 7dfdf024a39400f5082c364c8b6fef2567582134 Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Thu, 8 Aug 2024 11:06:28 +0100 Subject: [PATCH 58/61] Add credit note listener --- EventListener/StripeEventSubscriber.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/EventListener/StripeEventSubscriber.php b/EventListener/StripeEventSubscriber.php index b8cd385..7f63564 100755 --- a/EventListener/StripeEventSubscriber.php +++ b/EventListener/StripeEventSubscriber.php @@ -37,6 +37,9 @@ public static function getSubscribedEvents() StripeEvent::CHARGE_UPDATED => 'onStripeChargeEvent', StripeEvent::COUPON_CREATED => 'onStripeEvent', StripeEvent::COUPON_UPDATED => 'onStripeEvent', + StripeEvent::CREDIT_NOTE_CREATED => 'onStripeEvent', + StripeEvent::CREDIT_NOTE_UPDATED => 'onStripeEvent', + StripeEvent::CREDIT_NOTE_VOIDED => 'onStripeEvent', StripeEvent::CUSTOMER_CREATED => 'onStripeEvent', StripeEvent::CUSTOMER_UPDATED => 'onStripeEvent', StripeEvent::CUSTOMER_TAX_ID_CREATED => 'onStripeEvent', From 966109416558efe14b8f6626aad3abf5a12d015a Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Thu, 8 Aug 2024 12:14:10 +0100 Subject: [PATCH 59/61] Create AbstractCreditNoteModel --- Model/AbstractCreditNoteModel | 564 ++++++++++++++++++++++++++++++++++ 1 file changed, 564 insertions(+) create mode 100644 Model/AbstractCreditNoteModel diff --git a/Model/AbstractCreditNoteModel b/Model/AbstractCreditNoteModel new file mode 100644 index 0000000..fa00a47 --- /dev/null +++ b/Model/AbstractCreditNoteModel @@ -0,0 +1,564 @@ +currency; + } + + public function setCurrency(string $currency): AbstractCreditNoteModel + { + $this->currency = $currency; + + return $this; + } + + public function getInvoice(): string + { + return $this->invoice; + } + + /** + * @return AbstractCreditNoteModel + */ + public function setInvoice(string $invoice) + { + $this->invoice = $invoice; + + return $this; + } + + public function getLines(): array + { + return $this->lines; + } + + public function setLines(array $lines): AbstractCreditNoteModel + { + $this->lines = $lines; + + return $this; + } + + public function getMemo(): ?string + { + return $this->memo; + } + + public function setMemo(?string $memo): AbstractCreditNoteModel + { + $this->memo = $memo; + + return $this; + } + + public function getMetadata(): array + { + return $this->metadata; + } + + public function setMetadata(array $metadata): AbstractCreditNoteModel + { + $this->metadata = $metadata; + + return $this; + } + + public function getReason(): ?string + { + return $this->reason; + } + + public function setReason(?string $reason): AbstractCreditNoteModel + { + $this->reason = $reason; + + return $this; + } + + public function getStatus(): string + { + return $this->status; + } + + public function setStatus(string $status): AbstractCreditNoteModel + { + $this->status = $status; + + return $this; + } + + public function getSubtotal(): int + { + return $this->subtotal; + } + + public function setSubtotal(int $subtotal): AbstractCreditNoteModel + { + $this->subtotal = $subtotal; + + return $this; + } + + public function getTotal(): int + { + return $this->total; + } + + public function setTotal(int $total): AbstractCreditNoteModel + { + $this->total = $total; + + return $this; + } + + public function getObject(): string + { + return $this->object; + } + + public function setObject(string $object): AbstractCreditNoteModel + { + $this->object = $object; + + return $this; + } + + public function getAmount(): int + { + return $this->amount; + } + + public function setAmount(int $amount): AbstractCreditNoteModel + { + $this->amount = $amount; + + return $this; + } + + public function getAmountShipping(): int + { + return $this->amountShipping; + } + + public function setAmountShipping(int $amountShipping): AbstractCreditNoteModel + { + $this->amountShipping = $amountShipping; + + return $this; + } + + public function getCreated(): int + { + return $this->created; + } + + public function setCreated(int $created): AbstractCreditNoteModel + { + $this->created = $created; + + return $this; + } + + public function getCustomer(): string + { + return $this->customer; + } + + public function setCustomer(string $customer): AbstractCreditNoteModel + { + $this->customer = $customer; + + return $this; + } + + public function getCustomerBalanceTransaction(): ?string + { + return $this->customerBalanceTransaction; + } + + public function setCustomerBalanceTransaction(?string $customerBalanceTransaction): AbstractCreditNoteModel + { + $this->customerBalanceTransaction = $customerBalanceTransaction; + + return $this; + } + + public function getDiscountAmount(): int + { + return $this->discountAmount; + } + + public function setDiscountAmount(int $discountAmount): AbstractCreditNoteModel + { + $this->discountAmount = $discountAmount; + + return $this; + } + + public function getDiscountAmounts(): array + { + return $this->discountAmounts; + } + + public function setDiscountAmounts(array $discountAmounts): AbstractCreditNoteModel + { + $this->discountAmounts = $discountAmounts; + + return $this; + } + + public function getEffectiveAt(): ?int + { + return $this->effectiveAt; + } + + public function setEffectiveAt(?int $effectiveAt): AbstractCreditNoteModel + { + $this->effectiveAt = $effectiveAt; + + return $this; + } + + public function isLivemode(): bool + { + return $this->livemode; + } + + public function setLivemode(bool $livemode): AbstractCreditNoteModel + { + $this->livemode = $livemode; + + return $this; + } + + public function getNumber(): string + { + return $this->number; + } + + public function setNumber(string $number): AbstractCreditNoteModel + { + $this->number = $number; + + return $this; + } + + public function getOutOfBandAmount(): ?int + { + return $this->outOfBandAmount; + } + + public function setOutOfBandAmount(?int $outOfBandAmount): AbstractCreditNoteModel + { + $this->outOfBandAmount = $outOfBandAmount; + + return $this; + } + + public function getPdf(): string + { + return $this->pdf; + } + + public function setPdf(string $pdf): AbstractCreditNoteModel + { + $this->pdf = $pdf; + + return $this; + } + + public function getRefund(): ?string + { + return $this->refund; + } + + public function setRefund(?string $refund): AbstractCreditNoteModel + { + $this->refund = $refund; + + return $this; + } + + public function getShippingCost(): ?array + { + return $this->shippingCost; + } + + public function setShippingCost(?array $shippingCost): AbstractCreditNoteModel + { + $this->shippingCost = $shippingCost; + + return $this; + } + + public function getSubtotalExcludingTax(): ?int + { + return $this->subtotalExcludingTax; + } + + public function setSubtotalExcludingTax(?int $subtotalExcludingTax): AbstractCreditNoteModel + { + $this->subtotalExcludingTax = $subtotalExcludingTax; + + return $this; + } + + public function getTaxAmounts(): array + { + return $this->taxAmounts; + } + + public function setTaxAmounts(array $taxAmounts): AbstractCreditNoteModel + { + $this->taxAmounts = $taxAmounts; + + return $this; + } + + public function getTotalExcludingTax(): ?int + { + return $this->totalExcludingTax; + } + + public function setTotalExcludingTax(?int $totalExcludingTax): AbstractCreditNoteModel + { + $this->totalExcludingTax = $totalExcludingTax; + + return $this; + } + + public function getType(): string + { + return $this->type; + } + + public function setType(string $type): AbstractCreditNoteModel + { + $this->type = $type; + + return $this; + } + + public function getVoidedAt(): ?int + { + return $this->voidedAt; + } + + public function setVoidedAt(?int $voidedAt): AbstractCreditNoteModel + { + $this->voidedAt = $voidedAt; + + return $this; + } +} From 574a9f8e84901105e14829e1abe5067e1ab597eb Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Thu, 8 Aug 2024 15:21:43 +0100 Subject: [PATCH 60/61] Rename AbstractCreditNoteModel to AbstractCreditNoteModel.php --- Model/{AbstractCreditNoteModel => AbstractCreditNoteModel.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Model/{AbstractCreditNoteModel => AbstractCreditNoteModel.php} (100%) diff --git a/Model/AbstractCreditNoteModel b/Model/AbstractCreditNoteModel.php similarity index 100% rename from Model/AbstractCreditNoteModel rename to Model/AbstractCreditNoteModel.php From 1910cd77d783723bec2486bc72a65e60a07216cc Mon Sep 17 00:00:00 2001 From: Mark Ogilvie Date: Thu, 8 Aug 2024 17:22:02 +0100 Subject: [PATCH 61/61] Create AbstractDisputeModel.php --- Model/AbstractDisputeModel.php | 398 +++++++++++++++++++++++++++++++++ 1 file changed, 398 insertions(+) create mode 100644 Model/AbstractDisputeModel.php diff --git a/Model/AbstractDisputeModel.php b/Model/AbstractDisputeModel.php new file mode 100644 index 0000000..18bc58f --- /dev/null +++ b/Model/AbstractDisputeModel.php @@ -0,0 +1,398 @@ +amount; + } + + /** + * @param int $amount + * @return AbstractDisputeModel + */ + public function setAmount(int $amount): AbstractDisputeModel + { + $this->amount = $amount; + + return $this; + } + + /** + * @return string + */ + public function getCharge(): string + { + return $this->charge; + } + + /** + * @param string $charge + * @return AbstractDisputeModel + */ + public function setCharge(string $charge): AbstractDisputeModel + { + $this->charge = $charge; + + return $this; + } + + /** + * @return string + */ + public function getCurrency(): string + { + return $this->currency; + } + + /** + * @param string $currency + * @return AbstractDisputeModel + */ + public function setCurrency(string $currency): AbstractDisputeModel + { + $this->currency = $currency; + + return $this; + } + + /** + * @return array + */ + public function getEvidence(): array + { + return $this->evidence; + } + + /** + * @param array $evidence + * @return AbstractDisputeModel + */ + public function setEvidence(array $evidence): AbstractDisputeModel + { + $this->evidence = $evidence; + + return $this; + } + + /** + * @return array + */ + public function getMetadata(): array + { + return $this->metadata; + } + + /** + * @param array $metadata + * @return AbstractDisputeModel + */ + public function setMetadata(array $metadata): AbstractDisputeModel + { + $this->metadata = $metadata; + + return $this; + } + + /** + * @return string|null + */ + public function getPaymentIntent(): ?string + { + return $this->paymentIntent; + } + + /** + * @param string|null $paymentIntent + * @return AbstractDisputeModel + */ + public function setPaymentIntent(?string $paymentIntent): AbstractDisputeModel + { + $this->paymentIntent = $paymentIntent; + + return $this; + } + + /** + * @return string + */ + public function getReason(): string + { + return $this->reason; + } + + /** + * @param string $reason + * @return AbstractDisputeModel + */ + public function setReason(string $reason): AbstractDisputeModel + { + $this->reason = $reason; + + return $this; + } + + /** + * @return string + */ + public function getStatus(): string + { + return $this->status; + } + + /** + * @param string $status + * @return AbstractDisputeModel + */ + public function setStatus(string $status): AbstractDisputeModel + { + $this->status = $status; + + return $this; + } + + /** + * @return string + */ + public function getObject(): string + { + return $this->object; + } + + /** + * @param string $object + * @return AbstractDisputeModel + */ + public function setObject(string $object): AbstractDisputeModel + { + $this->object = $object; + + return $this; + } + + /** + * @return array + */ + public function getBalanceTransactions(): array + { + return $this->balanceTransactions; + } + + /** + * @param array $balanceTransactions + * @return AbstractDisputeModel + */ + public function setBalanceTransactions(array $balanceTransactions): AbstractDisputeModel + { + $this->balanceTransactions = $balanceTransactions; + + return $this; + } + + /** + * @return int + */ + public function getCreated(): int + { + return $this->created; + } + + /** + * @param int $created + * @return AbstractDisputeModel + */ + public function setCreated(int $created): AbstractDisputeModel + { + $this->created = $created; + + return $this; + } + + /** + * @return array + */ + public function getEvidenceDetails(): array + { + return $this->evidenceDetails; + } + + /** + * @param array $evidenceDetails + * @return AbstractDisputeModel + */ + public function setEvidenceDetails(array $evidenceDetails): AbstractDisputeModel + { + $this->evidenceDetails = $evidenceDetails; + + return $this; + } + + /** + * @return bool + */ + public function isChargeRefundable(): bool + { + return $this->isChargeRefundable; + } + + /** + * @param bool $isChargeRefundable + * @return AbstractDisputeModel + */ + public function setIsChargeRefundable(bool $isChargeRefundable): AbstractDisputeModel + { + $this->isChargeRefundable = $isChargeRefundable; + + return $this; + } + + /** + * @return bool + */ + public function isLivemode(): bool + { + return $this->livemode; + } + + /** + * @param bool $livemode + * @return AbstractDisputeModel + */ + public function setLivemode(bool $livemode): AbstractDisputeModel + { + $this->livemode = $livemode; + + return $this; + } + + /** + * @return array|null + */ + public function getPaymentMethodDetails(): ?array + { + return $this->paymentMethodDetails; + } + + /** + * @param array|null $paymentMethodDetails + * @return AbstractDisputeModel + */ + public function setPaymentMethodDetails(?array $paymentMethodDetails): AbstractDisputeModel + { + $this->paymentMethodDetails = $paymentMethodDetails; + + return $this; + } +}