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 index 6ada74d..7d9ebbd --- a/Controller/WebhookController.php +++ b/Controller/WebhookController.php @@ -5,14 +5,26 @@ use Miracode\StripeBundle\Event\StripeEvent; use Miracode\StripeBundle\Stripe\StripeObjectType; use Miracode\StripeBundle\StripeException; -use Symfony\Bundle\FrameworkBundle\Controller\Controller; +use Stripe\Error\SignatureVerification; +use Stripe\Exception\SignatureVerificationException; +use Stripe\Webhook; +use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; 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 { + + private $eventDispatcher; + + public function __construct(EventDispatcherInterface $eventDispatcher) + { + $this->eventDispatcher = $eventDispatcher; + } + /** * @param Request $request * @@ -21,14 +33,48 @@ 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 + $webhookSecret = $this->getParameter('miracode_stripe.webhook_secret'); + + $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(); + if (!$stripeEventObject = $stripeEventApi->retrieve($requestData->id)) { throw new StripeException( sprintf('Event does not exists, id %s', $requestData->id) @@ -36,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(); } 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 index 445c87c..91b3be2 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -15,19 +15,34 @@ class Configuration implements ConfigurationInterface /** * {@inheritdoc} */ - public function getConfigTreeBuilder() + public function getConfigTreeBuilder(): TreeBuilder { - $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) */); $rootNode ->children() + ->scalarNode('api_version') + ->defaultNull() + ->end() ->scalarNode('secret_key') ->isRequired() ->cannotBeEmpty() ->end() + ->scalarNode('webhook_secret') + ->defaultNull() + ->end() + ->booleanNode('use_bundle_subscriber') + ->defaultTrue() + ->end() ->arrayNode('database') ->children() ->scalarNode('driver') @@ -45,12 +60,17 @@ 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('payout')->cannotBeEmpty()->end() + ->scalarNode('product')->cannotBeEmpty()->end() + ->scalarNode('price')->cannotBeEmpty()->end() ->scalarNode('plan')->cannotBeEmpty()->end() ->scalarNode('refund')->cannotBeEmpty()->end() ->scalarNode('subscription')->cannotBeEmpty()->end() ->scalarNode('subscription_item')->cannotBeEmpty()->end() + ->scalarNode('tax_rate')->cannotBeEmpty()->end() ->end() ->end() ->end() diff --git a/DependencyInjection/MiracodeStripeExtension.php b/DependencyInjection/MiracodeStripeExtension.php old mode 100644 new mode 100755 index 7f6e7b0..6fd05a8 --- a/DependencyInjection/MiracodeStripeExtension.php +++ b/DependencyInjection/MiracodeStripeExtension.php @@ -35,6 +35,16 @@ public function load(array $configs, ContainerBuilder $container) $config['secret_key'] ); + $container->setParameter( + 'miracode_stripe.webhook_secret', + $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( @@ -48,7 +58,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/Event/StripeEvent.php b/Event/StripeEvent.php old mode 100644 new mode 100755 index b7f6c6a..0ffe919 --- a/Event/StripeEvent.php +++ b/Event/StripeEvent.php @@ -4,44 +4,84 @@ use Miracode\StripeBundle\StripeException; use Stripe\StripeObject; -use Symfony\Component\EventDispatcher\Event; +use Symfony\Contracts\EventDispatcher\Event; 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_TRAIL_WILL_END = 'stripe.customer.subscription.trial_will_end'; - const INVOICE_CREATED = 'stripe.invoice.created'; - 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 PLAN_CREATED = 'stripe.plan.created'; - const PLAN_DELETED = 'stripe.plan.deleted'; - const PLAN_UPDATED = 'stripe.plan.updated'; - const SOURCE_CANCELED = 'stripe.source.canceled'; - const SOURCE_CHARGEABLE = 'stripe.source.chargeable'; - const SOURCE_FAILED = 'stripe.source.failed'; + 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 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'; + 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'; + 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 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'; + 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/EventListener/StripeEventSubscriber.php b/EventListener/StripeEventSubscriber.php old mode 100644 new mode 100755 index b0b4d19..7f63564 --- a/EventListener/StripeEventSubscriber.php +++ b/EventListener/StripeEventSubscriber.php @@ -35,29 +35,39 @@ 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::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', + 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', 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_CREATED => 'onStripeEvent', StripeEvent::PLAN_UPDATED => 'onStripeEvent', 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', @@ -70,11 +80,13 @@ public static function getSubscribedEvents() public function onStripeEvent(StripeEvent $event) { $object = $event->getDataObject(); + if ($this->modelManager->support($object)) { $this->modelManager->save($object, true); } } + /** * @param StripeEvent $event */ 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 index 1df472a..a4ca9f6 --- 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\SafeDeleteModelInterface; use Miracode\StripeBundle\Model\StripeModelInterface; @@ -29,12 +30,11 @@ class DoctrineORMModelManager implements ModelManagerInterface /** * DoctrineORMModelManager constructor. - * @param ObjectManager $objectManager - * @param TransformerInterface $transformer + * * @param array $modelClasses */ public function __construct( - ObjectManager $objectManager, + EntityManagerInterface $objectManager, TransformerInterface $transformer, $modelClasses ) { @@ -44,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 */ @@ -56,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 */ @@ -68,18 +64,19 @@ public function retrieve(StripeObject $object) $modelClass = $this->modelClass($object); return $this->objectManager->getRepository($modelClass)->findOneBy([ - 'stripeId' => $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 retrieveByStripeId($id, $objectType) + public function retrieveById($id, $objectType) { $stripeObject = new StripeObject($id); $stripeObject->object = $objectType; @@ -88,9 +85,8 @@ public function retrieveByStripeId($id, $objectType) } /** - * Save stripe object in database + * Save stripe object in database. * - * @param StripeObject $object * @param bool $flush * * @return StripeModelInterface @@ -102,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(); @@ -112,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 @@ -138,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.'); } @@ -162,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 */ @@ -193,16 +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) { + $class->setId($object->id); + } - return new $className(); + return $class; } } diff --git a/Manager/ModelManagerInterface.php b/Manager/ModelManagerInterface.php old mode 100644 new mode 100755 index bb38e83..ab78a8f --- 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/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 index 7855fa8..54ba696 --- 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/AbstractCreditNoteModel.php b/Model/AbstractCreditNoteModel.php new file mode 100644 index 0000000..fa00a47 --- /dev/null +++ b/Model/AbstractCreditNoteModel.php @@ -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; + } +} diff --git a/Model/AbstractCustomerModel.php b/Model/AbstractCustomerModel.php old mode 100644 new mode 100755 index 9e186bf..3971215 --- 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; @@ -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/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; + } +} diff --git a/Model/AbstractInvoiceModel.php b/Model/AbstractInvoiceModel.php old mode 100644 new mode 100755 index 6b27fa1..516e0b8 --- 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") * @@ -41,6 +49,13 @@ abstract class AbstractInvoiceModel extends StripeModel */ protected $billing; + /** + * @StripeObjectParam(name="billing_reason") + * + * @var string + */ + protected $billingReason; + /** * @StripeObjectParam * @@ -209,6 +224,13 @@ abstract class AbstractInvoiceModel extends StripeModel */ protected $subtotal; + /** + * @StripeObjectParam + * + * @var array|null + */ + protected $discount; + /** * @StripeObjectParam * @@ -237,6 +259,40 @@ abstract class AbstractInvoiceModel extends StripeModel */ protected $webhooksDeliveredAt; + /** + * @StripeObjectParam(name="hosted_invoice_url") + * + * @var string|null + */ + protected $hostedInvoiceUrl; + + /** + * @StripeObjectParam(name="invoice_pdf") + * + * @var string|null + */ + 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 */ @@ -337,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 */ @@ -896,4 +971,72 @@ public function setWebhooksDeliveredAt($webhooksDeliveredAt) return $this; } + + /** + * @return string|null + */ + public function getHostedInvoiceUrl() + { + return $this->hostedInvoiceUrl; + } + + /** + * Set HostedInvoiceUrl. + * + * @param string|uull $hostedInvoiceUrl + * + * @return AbstractInvoiceModel + */ + public function setHostedInvoiceUrl($hostedInvoiceUrl): AbstractInvoiceModel + { + $this->hostedInvoiceUrl = $hostedInvoiceUrl; + + return $this; + } + + /** + * @return string|null + */ + public function getInvoicePdf() + { + return $this->invoicePdf; + } + + /** + * Set InvoicePdf. + * + * @param string|null $invoicePdf + * + * @return AbstractInvoiceModel + */ + public function setInvoicePdf($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/AbstractPayoutModel.php b/Model/AbstractPayoutModel.php new file mode 100755 index 0000000..b83b58e --- /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->arrivalDate; + } + + /** + * @param int $arrivalDate + * @return AbstractPayoutModel + */ + public function setArrivalDate($arrivalDate) + { + $this->arrivalDate = $arrivalDate; + + 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/Model/AbstractPlanModel.php b/Model/AbstractPlanModel.php old mode 100644 new mode 100755 index b96b3c4..f155a11 --- a/Model/AbstractPlanModel.php +++ b/Model/AbstractPlanModel.php @@ -6,6 +6,7 @@ abstract class AbstractPlanModel extends StripeModel { + /** * @StripeObjectParam * @@ -62,6 +63,13 @@ abstract class AbstractPlanModel extends StripeModel */ protected $name; + /** + * @StripeObjectParam(name="nickname") + * + * @var string + */ + protected $nickname; + /** * @StripeObjectParam(name="statement_descriptor") * @@ -76,6 +84,13 @@ abstract class AbstractPlanModel extends StripeModel */ protected $trialPeriodDays; + /** + * @StripeObjectParam + * + * @var bool + */ + protected $active; + /** * @return int */ @@ -275,4 +290,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/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 new file mode 100755 index 0000000..9368e08 --- /dev/null +++ b/Model/AbstractProductModel.php @@ -0,0 +1,418 @@ +active; + } + + /** + * @param bool $active + * @return AbstractProductModel + */ + public function setActive(bool $active): AbstractProductModel + { + $this->active = $active; + + return $this; + } + + /** + * @return string|null + */ + public function getDefaultPrice(): ?string + { + return $this->defaultPrice; + } + + /** + * @param string|null $defaultPrice + * @return AbstractProductModel + */ + public function setDefaultPrice(?string $defaultPrice): AbstractProductModel + { + $this->defaultPrice = $defaultPrice; + + return $this; + } + + /** + * @return string|null + */ + public function getDescription(): ?string + { + return $this->description; + } + + /** + * @param string|null $description + * @return AbstractProductModel + */ + public function setDescription(?string $description): AbstractProductModel + { + $this->description = $description; + + return $this; + } + + /** + * @return array + */ + public function getMetadata(): array + { + return $this->metadata; + } + + /** + * @param array $metadata + * @return AbstractProductModel + */ + public function setMetadata(array $metadata): AbstractProductModel + { + $this->metadata = $metadata; + + return $this; + } + + /** + * @return string + */ + public function getName(): string + { + return $this->name; + } + + /** + * @param string $name + * @return AbstractProductModel + */ + public function setName(string $name): AbstractProductModel + { + $this->name = $name; + + return $this; + } + + /** + * @return string + */ + public function getObject(): string + { + return $this->object; + } + + /** + * @param string $object + * @return AbstractProductModel + */ + public function setObject(string $object): AbstractProductModel + { + $this->object = $object; + + return $this; + } + + /** + * @return int + */ + public function getCreated(): int + { + return $this->created; + } + + /** + * @param int $created + * @return AbstractProductModel + */ + public function setCreated(int $created): AbstractProductModel + { + $this->created = $created; + + return $this; + } + + /** + * @return array + */ + public function getFeatures(): array + { + return $this->features; + } + + /** + * @param array $features + * @return AbstractProductModel + */ + public function setFeatures(array $features): AbstractProductModel + { + $this->features = $features; + + return $this; + } + + /** + * @return array + */ + public function getImages(): array + { + return $this->images; + } + + /** + * @param array $images + * @return AbstractProductModel + */ + public function setImages(array $images): AbstractProductModel + { + $this->images = $images; + + return $this; + } + + /** + * @return bool + */ + public function isLivemode(): bool + { + return $this->livemode; + } + + /** + * @param bool $livemode + * @return AbstractProductModel + */ + public function setLivemode(bool $livemode): AbstractProductModel + { + $this->livemode = $livemode; + + return $this; + } + + /** + * @return array|null + */ + public function getPackageDimensions(): ?array + { + return $this->packageDimensions; + } + + /** + * @param array|null $packageDimensions + * @return AbstractProductModel + */ + public function setPackageDimensions(?array $packageDimensions): AbstractProductModel + { + $this->packageDimensions = $packageDimensions; + + return $this; + } + + /** + * @return bool|null + */ + public function getShippable(): ?bool + { + return $this->shippable; + } + + /** + * @param bool|null $shippable + * @return AbstractProductModel + */ + public function setShippable(?bool $shippable): AbstractProductModel + { + $this->shippable = $shippable; + + return $this; + } + + /** + * @return string|null + */ + public function getStatementDescriptor(): ?string + { + return $this->statementDescriptor; + } + + /** + * @param string|null $statementDescriptor + * @return AbstractProductModel + */ + public function setStatementDescriptor(?string $statementDescriptor): AbstractProductModel + { + $this->statementDescriptor = $statementDescriptor; + + return $this; + } + + /** + * @return string|null + */ + public function getTaxCode(): ?string + { + return $this->taxCode; + } + + /** + * @param string|null $taxCode + * @return AbstractProductModel + */ + public function setTaxCode(?string $taxCode): AbstractProductModel + { + $this->taxCode = $taxCode; + + return $this; + } + + /** + * @return string|null + */ + 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|null $updated + * @return AbstractProductModel + */ + public function setUpdated(?int $updated): AbstractProductModel + { + $this->updated = $updated; + + return $this; + } + + /** + * @return string|null + */ + public function getUrl(): ?string + { + return $this->url; + } + + /** + * @param string|null $url + * @return AbstractProductModel + */ + public function setUrl(?string $url): AbstractProductModel + { + $this->url = $url; + + return $this; + } + +} 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 index b7249e2..28335a2 --- 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/AbstractTaxIdModel.php b/Model/AbstractTaxIdModel.php new file mode 100755 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 100755 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/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 index a1b87ea..69de487 --- a/Model/StripeModel.php +++ b/Model/StripeModel.php @@ -8,29 +8,23 @@ class StripeModel implements StripeModelInterface { /** * @StripeObjectParam(name="id") - * - * @var string */ - protected $stripeId; + protected string $id; /** - * Retrieve stripe object ID - * - * @return string + * Retrieve stripe object ID. */ - public function getStripeId() + public function getId(): string { - return $this->stripeId; + return $this->id; } /** - * @param string $stripeId - * * @return $this */ - public function setStripeId($stripeId) + public function setId(string $id): static { - $this->stripeId = $stripeId; + $this->id = $id; return $this; } diff --git a/Model/StripeModelInterface.php b/Model/StripeModelInterface.php old mode 100644 new mode 100755 index 8615873..b6afe05 --- 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/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 index 0886182..db0e53a --- a/README.md +++ b/README.md @@ -2,12 +2,8 @@ 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) Installation @@ -41,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%" ``` @@ -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 @@ -84,14 +97,14 @@ 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 { public static function getSubscribedEvents() { return [ - 'stripe.charge.succeeded' => 'onChargeSucceededEvent', + StripeEvent::CHARGE_SUCCEEDED => 'onChargeSucceededEvent', ]; } @@ -100,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\Contracts\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. @@ -117,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` @@ -208,4 +274,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. diff --git a/Resources/config/doctrine/model/AbstractCardModel.orm.xml b/Resources/config/doctrine/model/AbstractCardModel.orm.xml old mode 100644 new mode 100755 index 09e3558..f7d9262 --- 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 old mode 100644 new mode 100755 index dad023e..b4950c2 --- 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 old mode 100644 new mode 100755 index 67c966c..a860af9 --- a/Resources/config/doctrine/model/AbstractCouponModel.orm.xml +++ b/Resources/config/doctrine/model/AbstractCouponModel.orm.xml @@ -6,6 +6,7 @@ + @@ -14,13 +15,10 @@ - + - - - diff --git a/Resources/config/doctrine/model/AbstractCustomerModel.orm.xml b/Resources/config/doctrine/model/AbstractCustomerModel.orm.xml old mode 100644 new mode 100755 index f23a7ff..c6b2884 --- 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 old mode 100644 new mode 100755 index 8a5338f..db7725a --- a/Resources/config/doctrine/model/AbstractInvoiceModel.orm.xml +++ b/Resources/config/doctrine/model/AbstractInvoiceModel.orm.xml @@ -5,6 +5,7 @@ + @@ -30,18 +31,18 @@ - + + + + - - - diff --git a/Resources/config/doctrine/model/AbstractPayoutModel.orm.xml b/Resources/config/doctrine/model/AbstractPayoutModel.orm.xml new file mode 100755 index 0000000..f55a7d6 --- /dev/null +++ b/Resources/config/doctrine/model/AbstractPayoutModel.orm.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Resources/config/doctrine/model/AbstractPlanModel.orm.xml b/Resources/config/doctrine/model/AbstractPlanModel.orm.xml old mode 100644 new mode 100755 index 86197fc..1a8d0ee --- a/Resources/config/doctrine/model/AbstractPlanModel.orm.xml +++ b/Resources/config/doctrine/model/AbstractPlanModel.orm.xml @@ -12,13 +12,12 @@ + - + + - - - \ No newline at end of file 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 new file mode 100755 index 0000000..1f8da89 --- /dev/null +++ b/Resources/config/doctrine/model/AbstractProductModel.orm.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Resources/config/doctrine/model/AbstractRefundModel.orm.xml b/Resources/config/doctrine/model/AbstractRefundModel.orm.xml old mode 100644 new mode 100755 index f6f8aeb..ca67907 --- 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 old mode 100644 new mode 100755 index bc3eff0..476b36b --- 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/Resources/config/doctrine/model/AbstractTaxIdModel.orm.xml b/Resources/config/doctrine/model/AbstractTaxIdModel.orm.xml new file mode 100755 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 100755 index 0000000..89bfcbe --- /dev/null +++ b/Resources/config/doctrine/model/AbstractTaxRateModel.orm.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + 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 index 4f56ce3..5acc04d --- 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 diff --git a/Resources/config/services.xml b/Resources/config/services.xml old mode 100644 new mode 100755 index 8c3bde0..a0cbd74 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -5,9 +5,18 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> + + + + + + + + + %miracode_stripe.secret_key% + - diff --git a/Stripe/StripeClient.php b/Stripe/StripeClient.php new file mode 100755 index 0000000..582b5b9 --- /dev/null +++ b/Stripe/StripeClient.php @@ -0,0 +1,534 @@ + $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 (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); + } + + 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 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 (is_array($parameters) && !empty($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); + } + + /** + * @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, $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); + } +} 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 index 6f9fc1f..52f4bd2 --- 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 = <<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,19 +46,19 @@ 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) { - return $obj->__toArray(true); + $value = array_map(function (StripeObject $obj) { + return $obj->toArray(true); }, $value->data); } else { - $value = $value->__toArray(true); + $value = $value->toArray(true); } } } - $setter = 'set' . ucfirst($prop->getName()); + $setter = 'set'.ucfirst($prop->getName()); call_user_func([$model, $setter], $value); } } 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 index b480d3b..cf7d4d4 --- 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", diff --git a/phpunit.xml.dist b/phpunit.xml.dist old mode 100644 new mode 100755