diff --git a/app/controllers/customers_controller.rb b/app/controllers/customers_controller.rb new file mode 100644 index 0000000..4839e31 --- /dev/null +++ b/app/controllers/customers_controller.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module DiscoursePatrons + class CustomersController < ::ApplicationController + include DiscoursePatrons::Stripe + + before_action :set_api_key + + def create + customer = ::Stripe::Customer.create( + email: current_user.email, + source: params[:source] + ) + + render_json_dump customer + end + end +end diff --git a/assets/javascripts/discourse/components/subscribe-card.js.es6 b/assets/javascripts/discourse/components/subscribe-card.js.es6 new file mode 100644 index 0000000..d773d59 --- /dev/null +++ b/assets/javascripts/discourse/components/subscribe-card.js.es6 @@ -0,0 +1,7 @@ +export default Ember.Component.extend({ + didInsertElement() { + this._super(...arguments); + this.cardElement.mount("#card-element"); + }, + didDestroyElement() {} +}); diff --git a/assets/javascripts/discourse/controllers/patrons-index.js.es6 b/assets/javascripts/discourse/controllers/patrons-index.js.es6 index ad83561..803e911 100644 --- a/assets/javascripts/discourse/controllers/patrons-index.js.es6 +++ b/assets/javascripts/discourse/controllers/patrons-index.js.es6 @@ -13,7 +13,7 @@ export default Ember.Controller.extend({ }, paymentSuccessHandler(paymentIntentId) { - DiscourseURL.redirectTo(`patrons/${paymentIntentId}`); + // DiscourseURL.redirectTo(`patrons/${paymentIntentId}`); } } }); diff --git a/assets/javascripts/discourse/controllers/patrons-subscribe.js.es6 b/assets/javascripts/discourse/controllers/patrons-subscribe.js.es6 index 8e16cae..caac906 100644 --- a/assets/javascripts/discourse/controllers/patrons-subscribe.js.es6 +++ b/assets/javascripts/discourse/controllers/patrons-subscribe.js.es6 @@ -1,11 +1,37 @@ -export default Ember.Controller.extend({ - actions: { - stripePaymentHandler(/* data */) { - // console.log('stripePaymentHandler', data); - }, +import { ajax } from "discourse/lib/ajax"; - paymentSuccessHandler(/* paymentIntentId */) { - // console.log('paymentSuccessHandler'); +export default Ember.Controller.extend({ + init() { + this._super(...arguments); + this.set( + "stripe", + Stripe(Discourse.SiteSettings.discourse_patrons_public_key) + ); + const elements = this.get("stripe").elements(); + this.set("cardElement", elements.create("card", { hidePostalCode: true })); + }, + + actions: { + stripePaymentHandler() { + // https://stripe.com/docs/billing/subscriptions/payment#signup-flow + + this.stripe.createToken(this.get("cardElement")).then(result => { + if (result.error) { + // Inform the customer that there was an error. + // var errorElement = document.getElementById('card-errors'); + // errorElement.textContent = result.error.message; + } else { + const data = { + source: result.token.id + }; + + return ajax("/patrons/customers", { method: "post", data }).then( + result => { + // create subscription + } + ); + } + }); } } }); diff --git a/assets/javascripts/discourse/templates/components/subscribe-card.hbs b/assets/javascripts/discourse/templates/components/subscribe-card.hbs new file mode 100644 index 0000000..f2afe6e --- /dev/null +++ b/assets/javascripts/discourse/templates/components/subscribe-card.hbs @@ -0,0 +1,2 @@ + +
diff --git a/assets/javascripts/discourse/templates/patrons/subscribe.hbs b/assets/javascripts/discourse/templates/patrons/subscribe.hbs index 940fe65..1562aed 100644 --- a/assets/javascripts/discourse/templates/patrons/subscribe.hbs +++ b/assets/javascripts/discourse/templates/patrons/subscribe.hbs @@ -13,8 +13,22 @@
{{combo-box valueAttribute="id" content=model.plans value=model.plan}} - {{#d-button class="btn btn-primary btn-payment btn-discourse-patrons"}} + {{#d-button + action="stripePaymentHandler" + class="btn btn-primary btn-payment btn-discourse-patrons"}} {{i18n 'discourse_patrons.subscribe.buttons.subscribe'}} {{/d-button}} + +
+ +

{{i18n 'discourse_patrons.subscribe.card.title'}}

+ {{subscribe-card cardElement=cardElement}} + +
+

{{i18n 'discourse_patrons.subscribe.customer.title'}}

+
+ {{i18n 'discourse_patrons.subscribe.customer.empty'}} +
+
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 78c563c..b3c4929 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -20,6 +20,11 @@ en: subscribe: Subscribe subscribe: title: Subscribe + card: + title: Payment + customer: + title: Customer Details + empty: We couldn't find a customer identifier in our system. A new one will be created for you. buttons: subscribe: Subscribe one_time: diff --git a/config/routes.rb b/config/routes.rb index 9b23cbe..64d6e40 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -11,6 +11,7 @@ DiscoursePatrons::Engine.routes.draw do resources :subscriptions, only: [:index] end + resources :customers, only: [:create] resources :plans, only: [:index] resources :patrons, only: [:index, :create] diff --git a/plugin.rb b/plugin.rb index 8e9ab8a..c6a519e 100644 --- a/plugin.rb +++ b/plugin.rb @@ -41,6 +41,7 @@ after_initialize do "../app/controllers/admin_controller", "../app/controllers/admin/plans_controller", "../app/controllers/admin/subscriptions_controller", + "../app/controllers/customers_controller", "../app/controllers/patrons_controller", "../app/controllers/plans_controller", "../app/models/payment", diff --git a/spec/requests/customers_controller_spec.rb b/spec/requests/customers_controller_spec.rb new file mode 100644 index 0000000..0d8f0f7 --- /dev/null +++ b/spec/requests/customers_controller_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'rails_helper' + +module DiscoursePatrons + RSpec.describe CustomersController do + describe "create" do + let(:user) { Fabricate(:user, email: 'hello.2@example.com') } + + before do + sign_in(user) + end + + it "creates a customer" do + ::Stripe::Customer.expects(:create).with( + email: 'hello.2@example.com', + source: 'tok_interesting' + ) + + post "/patrons/customers.json", params: { source: 'tok_interesting' } + end + end + end +end diff --git a/test/javascripts/acceptance/subscribe-test.js.es6 b/test/javascripts/acceptance/subscribe-test.js.es6 index 026b5bc..ea14121 100644 --- a/test/javascripts/acceptance/subscribe-test.js.es6 +++ b/test/javascripts/acceptance/subscribe-test.js.es6 @@ -11,3 +11,11 @@ QUnit.test("subscribing", async assert => { assert.ok($("h3").length, "has a heading"); }); + +QUnit.test("subscribing with empty customer", async assert => { + await visit("/patrons/subscribe"); + assert.ok( + $(".discourse-patrons-subscribe-customer-empty").length, + "has empty customer content" + ); +});