Repository: stripe/stripe-node
Pull request #973 (2020-08-05 01:38:36)

Multiple API changes
Multiple API changes:
  * Add support for the `PromotionCode` resource and APIs
  * Add support for `allow_promotion_codes` on Checkout `Session`
  * Add support for `applies_to[products]` on `Coupon`
  * Add support for `promotion_code` on `Customer` and `Subscription`
  * Add support for `promotion_code` on `Discount`

Codegen for openapi f71053e

r? @cjavilla-stripe 
cc @stripe/api-libraries 


Patch:
diff --git a/lib/resources.js b/lib/resources.js
index e471994b..42f3eada 100644
--- a/lib/resources.js
+++ b/lib/resources.js
@@ -37,6 +37,7 @@ module.exports = {
   Plans: require('./resources/Plans'),
   Prices: require('./resources/Prices'),
   Products: require('./resources/Products'),
+  PromotionCodes: require('./resources/PromotionCodes'),
   Refunds: require('./resources/Refunds'),
   Reviews: require('./resources/Reviews'),
   SetupIntents: require('./resources/SetupIntents'),
diff --git a/lib/resources/PromotionCodes.js b/lib/resources/PromotionCodes.js
new file mode 100644
index 00000000..fcfa93c2
--- /dev/null
+++ b/lib/resources/PromotionCodes.js
@@ -0,0 +1,11 @@
+// File generated from our OpenAPI spec
+
+'use strict';
+
+const StripeResource = require('../StripeResource');
+
+module.exports = StripeResource.extend({
+  path: 'promotion_codes',
+
+  includeBasic: ['create', 'list', 'retrieve', 'update'],
+});
diff --git a/types/2020-03-02/Checkout/Sessions.d.ts b/types/2020-03-02/Checkout/Sessions.d.ts
index 3943a66d..16d7334c 100644
--- a/types/2020-03-02/Checkout/Sessions.d.ts
+++ b/types/2020-03-02/Checkout/Sessions.d.ts
@@ -17,6 +17,11 @@ declare module 'stripe' {
          */
         object: 'checkout.session';
 
+        /**
+         * Enables user redeemable promotion codes.
+         */
+        allow_promotion_codes?: boolean | null;
+
         /**
          * Total of all items before discounts or taxes are applied.
          */
@@ -621,6 +626,11 @@ declare module 'stripe' {
          */
         success_url: string;
 
+        /**
+         * Enables user redeemable promotion codes.
+         */
+        allow_promotion_codes?: boolean;
+
         /**
          * Specify whether Checkout should collect the customer's billing address.
          */
diff --git a/types/2020-03-02/Coupons.d.ts b/types/2020-03-02/Coupons.d.ts
index c2e68579..0e1a826e 100644
--- a/types/2020-03-02/Coupons.d.ts
+++ b/types/2020-03-02/Coupons.d.ts
@@ -20,6 +20,8 @@ declare module 'stripe' {
        */
       amount_off: number | null;
 
+      applies_to?: Coupon.AppliesTo;
+
       /**
        * Time at which the object was created. Measured in seconds since the Unix epoch.
        */
@@ -84,6 +86,13 @@ declare module 'stripe' {
     }
 
     namespace Coupon {
+      interface AppliesTo {
+        /**
+         * A list of product IDs this coupon applies to
+         */
+        products: Array<string>;
+      }
+
       type Duration = 'forever' | 'once' | 'repeating';
     }
 
@@ -118,6 +127,11 @@ declare module 'stripe' {
        */
       amount_off?: number;
 
+      /**
+       * A hash containing directions for what this Coupon will apply discounts to.
+       */
+      applies_to?: CouponCreateParams.AppliesTo;
+
       /**
        * Three-letter [ISO code for the currency](https://stripe.com/docs/currencies) of the `amount_off` parameter (required if `amount_off` is passed).
        */
@@ -165,6 +179,13 @@ declare module 'stripe' {
     }
 
     namespace CouponCreateParams {
+      interface AppliesTo {
+        /**
+         * An array of Product IDs that this Coupon will apply to.
+         */
+        products: Array<string>;
+      }
+
       type Duration = 'forever' | 'once' | 'repeating';
     }
 
diff --git a/types/2020-03-02/Customers.d.ts b/types/2020-03-02/Customers.d.ts
index b3d1f46c..254d8f1f 100644
--- a/types/2020-03-02/Customers.d.ts
+++ b/types/2020-03-02/Customers.d.ts
@@ -271,6 +271,11 @@ declare module 'stripe' {
        */
       preferred_locales?: Array<string>;
 
+      /**
+       * The API ID of a promotion code to apply to the customer. The customer will have a discount applied on all recurring payments. Charges you create through the API will not have the discount.
+       */
+      promotion_code?: string;
+
       /**
        * The customer's shipping information. Appears on invoices emailed to this customer.
        */
@@ -466,6 +471,11 @@ declare module 'stripe' {
        */
       preferred_locales?: Array<string>;
 
+      /**
+       * The API ID of a promotion code to apply to the customer. The customer will have a discount applied on all recurring payments. Charges you create through the API will not have the discount.
+       */
+      promotion_code?: string;
+
       /**
        * The customer's shipping information. Appears on invoices emailed to this customer.
        */
diff --git a/types/2020-03-02/Discounts.d.ts b/types/2020-03-02/Discounts.d.ts
index 0037981e..b38e403e 100644
--- a/types/2020-03-02/Discounts.d.ts
+++ b/types/2020-03-02/Discounts.d.ts
@@ -44,6 +44,11 @@ declare module 'stripe' {
        */
       invoice_item?: string | null;
 
+      /**
+       * The promotion code applied to create this discount.
+       */
+      promotion_code?: string | Stripe.PromotionCode | null;
+
       /**
        * Date that the coupon was applied.
        */
@@ -96,6 +101,11 @@ declare module 'stripe' {
        */
       invoice_item?: string | null;
 
+      /**
+       * The promotion code applied to create this discount.
+       */
+      promotion_code?: string | Stripe.PromotionCode | null;
+
       /**
        * Date that the coupon was applied.
        */
diff --git a/types/2020-03-02/PromotionCodes.d.ts b/types/2020-03-02/PromotionCodes.d.ts
new file mode 100644
index 00000000..dee23893
--- /dev/null
+++ b/types/2020-03-02/PromotionCodes.d.ts
@@ -0,0 +1,255 @@
+// File generated from our OpenAPI spec
+declare module 'stripe' {
+  namespace Stripe {
+    /**
+     * The PromotionCode object.
+     */
+    interface PromotionCode {
+      /**
+       * Unique identifier for the object.
+       */
+      id: string;
+
+      /**
+       * String representing the object's type. Objects of the same type share the same value.
+       */
+      object: 'promotion_code';
+
+      /**
+       * Whether the promotion code is currently active. A promotion code is only active if the coupon is also valid.
+       */
+      active: boolean;
+
+      /**
+       * The customer-facing code. Regardless of case, this code must be unique across all active promotion codes for each customer.
+       */
+      code: string;
+
+      /**
+       * A coupon contains information about a percent-off or amount-off discount you
+       * might want to apply to a customer. Coupons may be applied to [invoices](https://stripe.com/docs/api#invoices) or
+       * [orders](https://stripe.com/docs/api#create_order-coupon). Coupons do not work with conventional one-off [charges](https://stripe.com/docs/api#create_charge).
+       */
+      coupon: Stripe.Coupon;
+
+      /**
+       * Time at which the object was created. Measured in seconds since the Unix epoch.
+       */
+      created: number;
+
+      /**
+       * The customer that this promotion code can be used by.
+       */
+      customer: string | Stripe.Customer | Stripe.DeletedCustomer | null;
+
+      /**
+       * Date at which the promotion code can no longer be redeemed.
+       */
+      expires_at: number | null;
+
+      /**
+       * Has the value `true` if the object exists in live mode or the value `false` if the object exists in test mode.
+       */
+      livemode: boolean;
+
+      /**
+       * Maximum number of times this promotion code can be redeemed.
+       */
+      max_redemptions: number | null;
+
+      /**
+       * Set of [key-value pairs](https://stripe.com/docs/api/metadata) that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
+       */
+      metadata: Metadata;
+
+      restrictions?: PromotionCode.Restrictions;
+
+      /**
+       * Number of times this promotion code has been used.
+       */
+      times_redeemed: number;
+    }
+
+    namespace PromotionCode {
+      interface Restrictions {
+        /**
+         * A Boolean indicating if the Promotion Code should only be redeemed for Customers without any successful payments or invoices
+         */
+        first_time_transaction: boolean;
+
+        /**
+         * Minimum amount required to redeem this Promotion Code into a Coupon (e.g., a purchase must be $100 or more to work).
+         */
+        minimum_amount: number | null;
+
+        /**
+         * Three-letter [ISO code](https://stripe.com/docs/currencies) for minimum_amount
+         */
+        minimum_amount_currency: string | null;
+      }
+    }
+
+    interface PromotionCodeCreateParams {
+      /**
+       * The coupon for this promotion code.
+       */
+      coupon: string;
+
+      /**
+       * Whether the promotion code is currently active.
+       */
+      active?: boolean;
+
+      /**
+       * The customer-facing code. Regardless of case, this code must be unique across all active promotion codes for a specific customer. If left blank, we will generate one automatically.
+       */
+      code?: string;
+
+      /**
+       * The customer that this promotion code can be used by. If not set, the promotion code can be used by all customers.
+       */
+      customer?: string;
+
+      /**
+       * Specifies which fields in the response should be expanded.
+       */
+      expand?: Array<string>;
+
+      /**
+       * The timestamp at which this promotion code will expire. If the coupon has specified a `redeems_by`, then this value cannot be after the coupon's `redeems_by`.
+       */
+      expires_at?: number;
+
+      /**
+       * A positive integer specifying the number of times the promotion code can be redeemed. If the coupon has specified a `max_redemptions`, then this value cannot be greater than the coupon's `max_redemptions`.
+       */
+      max_redemptions?: number;
+
+      /**
+       * Set of [key-value pairs](https://stripe.com/docs/api/metadata) that you can attach to an object. This can be useful for storing additional information about the object in a structured format. Individual keys can be unset by posting an empty value to them. All keys can be unset by posting an empty value to `metadata`.
+       */
+      metadata?: MetadataParam;
+
+      /**
+       * Settings that restrict the redemption of the promotion code.
+       */
+      restrictions?: PromotionCodeCreateParams.Restrictions;
+    }
+
+    namespace PromotionCodeCreateParams {
+      interface Restrictions {
+        /**
+         * A Boolean indicating if the Promotion Code should only be redeemed for Customers without any successful payments or invoices
+         */
+        first_time_transaction?: boolean;
+
+        /**
+         * Minimum amount required to redeem this Promotion Code into a Coupon (e.g., a purchase must be $100 or more to work).
+         */
+        minimum_amount?: number;
+
+        /**
+         * Three-letter [ISO code](https://stripe.com/docs/currencies) for minimum_amount
+         */
+        minimum_amount_currency?: string;
+      }
+    }
+
+    interface PromotionCodeRetrieveParams {
+      /**
+       * Specifies which fields in the response should be expanded.
+       */
+      expand?: Array<string>;
+    }
+
+    interface PromotionCodeUpdateParams {
+      /**
+       * Whether the promotion code is currently active. A promotion code can only be reactivated when the coupon is still valid and the promotion code is otherwise redeemable.
+       */
+      active?: boolean;
+
+      /**
+       * Specifies which fields in the response should be expanded.
+       */
+      expand?: Array<string>;
+
+      /**
+       * Set of [key-value pairs](https://stripe.com/docs/api/metadata) that you can attach to an object. This can be useful for storing additional information about the object in a structured format. Individual keys can be unset by posting an empty value to them. All keys can be unset by posting an empty value to `metadata`.
+       */
+      metadata?: MetadataParam | null;
+    }
+
+    interface PromotionCodeListParams extends PaginationParams {
+      /**
+       * Filter promotion codes by whether they are active.
+       */
+      active?: boolean;
+
+      /**
+       * Only return promotion codes that have this case-insensitive code.
+       */
+      code?: string;
+
+      /**
+       * Only return promotion codes for this coupon.
+       */
+      coupon?: string;
+
+      /**
+       * A filter on the list, based on the object `created` field. The value can be a string with an integer Unix timestamp, or it can be a dictionary with a number of different query options.
+       */
+      created?: RangeQueryParam | number;
+
+      /**
+       * Only return promotion codes that are restricted to this customer.
+       */
+      customer?: string;
+
+      /**
+       * Specifies which fields in the response should be expanded.
+       */
+      expand?: Array<string>;
+    }
+
+    class PromotionCodesResource {
+      /**
+       * A promotion code points to a coupon. You can optionally restrict the code to a specific customer, redemption limit, and expiration date.
+       */
+      create(
+        params: PromotionCodeCreateParams,
+        options?: RequestOptions
+      ): Promise<Stripe.PromotionCode>;
+
+      /**
+       * Retrieves the promotion code with the given ID.
+       */
+      retrieve(
+        id: string,
+        params?: PromotionCodeRetrieveParams,
+        options?: RequestOptions
+      ): Promise<Stripe.PromotionCode>;
+      retrieve(
+        id: string,
+        options?: RequestOptions
+      ): Promise<Stripe.PromotionCode>;
+
+      /**
+       * Updates the specified promotion code by setting the values of the parameters passed. Most fields are, by design, not editable.
+       */
+      update(
+        id: string,
+        params?: PromotionCodeUpdateParams,
+        options?: RequestOptions
+      ): Promise<Stripe.PromotionCode>;
+
+      /**
+       * Returns a list of your promotion codes.
+       */
+      list(
+        params?: PromotionCodeListParams,
+        options?: RequestOptions
+      ): ApiListPromise<Stripe.PromotionCode>;
+      list(options?: RequestOptions): ApiListPromise<Stripe.PromotionCode>;
+    }
+  }
+}
diff --git a/types/2020-03-02/Subscriptions.d.ts b/types/2020-03-02/Subscriptions.d.ts
index ae943fe2..9f6b76d3 100644
--- a/types/2020-03-02/Subscriptions.d.ts
+++ b/types/2020-03-02/Subscriptions.d.ts
@@ -400,6 +400,11 @@ declare module 'stripe' {
        */
       pending_invoice_item_interval?: SubscriptionCreateParams.PendingInvoiceItemInterval | null;
 
+      /**
+       * The API ID of a promotion code to apply to this subscription. A promotion code applied to a subscription will only affect invoices created for that particular subscription.
+       */
+      promotion_code?: string;
+
       /**
        * This field has been renamed to `proration_behavior`. `prorate=true` can be replaced with `proration_behavior=create_prorations` and `prorate=false` can be replaced with `proration_behavior=none`.
        */
@@ -728,6 +733,11 @@ declare module 'stripe' {
        */
       pending_invoice_item_interval?: SubscriptionUpdateParams.PendingInvoiceItemInterval | null;
 
+      /**
+       * The promotion code to apply to this subscription. A promotion code applied to a subscription will only affect invoices created for that particular subscription.
+       */
+      promotion_code?: string;
+
       /**
        * This field has been renamed to `proration_behavior`. `prorate=true` can be replaced with `proration_behavior=create_prorations` and `prorate=false` can be replaced with `proration_behavior=none`.
        */
diff --git a/types/2020-03-02/index.d.ts b/types/2020-03-02/index.d.ts
index 0e0e4d0d..36185d55 100644
--- a/types/2020-03-02/index.d.ts
+++ b/types/2020-03-02/index.d.ts
@@ -61,6 +61,7 @@
 ///<reference path='./PlatformTaxFees.d.ts' />
 ///<reference path='./Prices.d.ts' />
 ///<reference path='./Products.d.ts' />
+///<reference path='./PromotionCodes.d.ts' />
 ///<reference path='./Radar/EarlyFraudWarnings.d.ts' />
 ///<reference path='./Radar/ValueListItems.d.ts' />
 ///<reference path='./Radar/ValueLists.d.ts' />
@@ -136,6 +137,7 @@ declare module 'stripe' {
     plans: Stripe.PlansResource;
     prices: Stripe.PricesResource;
     products: Stripe.ProductsResource;
+    promotionCodes: Stripe.PromotionCodesResource;
     refunds: Stripe.RefundsResource;
     reviews: Stripe.ReviewsResource;
     setupIntents: Stripe.SetupIntentsResource;


Test patch:
diff --git a/test/resources/PromotionCodes.spec.js b/test/resources/PromotionCodes.spec.js
new file mode 100644
index 00000000..bbcc012e
--- /dev/null
+++ b/test/resources/PromotionCodes.spec.js
@@ -0,0 +1,69 @@
+'use strict';
+
+const stripe = require('../../testUtils').getSpyableStripe();
+const expect = require('chai').expect;
+
+describe('PromotionCodes Resource', () => {
+  describe('retrieve', () => {
+    it('Sends the correct request', () => {
+      stripe.promotionCodes.retrieve('promo_123');
+      expect(stripe.LAST_REQUEST).to.deep.equal({
+        method: 'GET',
+        url: '/v1/promotion_codes/promo_123',
+        headers: {},
+        data: {},
+        settings: {},
+      });
+    });
+  });
+
+  describe('update', () => {
+    it('Sends the correct request', () => {
+      stripe.promotionCodes.update('promo_123', {
+        metadata: {a: '1234'},
+      });
+      expect(stripe.LAST_REQUEST).to.deep.equal({
+        method: 'POST',
+        url: '/v1/promotion_codes/promo_123',
+        headers: {},
+        data: {
+          metadata: {a: '1234'},
+        },
+        settings: {},
+      });
+    });
+  });
+
+  describe('create', () => {
+    it('Sends the correct request', () => {
+      stripe.promotionCodes.create({
+        coupon: 'co_123',
+        code: 'MYCODE',
+      });
+
+      expect(stripe.LAST_REQUEST).to.deep.equal({
+        method: 'POST',
+        url: '/v1/promotion_codes',
+        headers: {},
+        data: {
+          coupon: 'co_123',
+          code: 'MYCODE',
+        },
+        settings: {},
+      });
+    });
+  });
+
+  describe('list', () => {
+    it('Sends the correct request', () => {
+      stripe.promotionCodes.list();
+      expect(stripe.LAST_REQUEST).to.deep.equal({
+        method: 'GET',
+        url: '/v1/promotion_codes',
+        headers: {},
+        data: {},
+        settings: {},
+      });
+    });
+  });
+});