Basic UI for adding credit card details and getting a Stripe token without making a payment

This commit is contained in:
stveep
2017-05-01 11:03:23 +01:00
committed by Rob Harrington
parent c6e50a3f7f
commit 1449169b16
9 changed files with 134 additions and 21 deletions

View File

@@ -1,4 +1,4 @@
Darkswarm.controller "PaymentCtrl", ($scope, $timeout, savedCreditCards) ->
Darkswarm.controller "PaymentCtrl", ($scope, $timeout, savedCreditCards, Dates) ->
angular.extend(this, new FieldsetMixin($scope))
defaultCard = [ {id: null, formatted: t("new_credit_card")} ]
$scope.savedCreditCards = defaultCard.concat savedCreditCards if savedCreditCards
@@ -7,22 +7,9 @@ Darkswarm.controller "PaymentCtrl", ($scope, $timeout, savedCreditCards) ->
$scope.name = "payment"
$scope.months = [
{key: t("january"), value: "1"},
{key: t("february"), value: "2"},
{key: t("march"), value: "3"},
{key: t("april"), value: "4"},
{key: t("may"), value: "5"},
{key: t("june"), value: "6"},
{key: t("july"), value: "7"},
{key: t("august"), value: "8"},
{key: t("september"), value: "9"},
{key: t("october"), value: "10"},
{key: t("november"), value: "11"},
{key: t("december"), value: "12"},
]
$scope.months = Dates.months
$scope.years = [moment().year()..(moment().year()+15)]
$scope.years = Dates.years
$scope.secrets.card_month = "1"
$scope.secrets.card_year = moment().year()

View File

@@ -0,0 +1,25 @@
Darkswarm.controller "CreditCardsCtrl", ($scope, $timeout, CreditCard, savedCreditCards, StripeJS, Dates, Loading) ->
angular.extend(this, new FieldsetMixin($scope))
$scope.savedCreditCards = savedCreditCards
$scope.CreditCard = CreditCard
$scope.allow_name_change = true
$scope.disable_fields = false
$scope.months = Dates.months
$scope.years = Dates.years
$scope.secrets = CreditCard.secrets
$scope.storeCard = =>
Loading.message = "Saving"
CreditCard.requestToken($scope.secrets)
# Need to call Spree::Gateway::StripeConnect#provider.store(creditcard)
# creditcard should be formatted as for a payment
# The token then needs to be associated with the Customer (in Stripe) - can be done in Ruby.

View File

@@ -0,0 +1,16 @@
Darkswarm.factory 'CreditCard', ($injector, $rootScope, StripeJS, Navigation, $http, RailsFlashLoader, Loading)->
new class CreditCard
errors: {}
requestToken: (secrets) ->
#$scope.secrets.name = $scope.secrets.first_name + " " + $scope.secrets.last_name
secrets.name = @full_name(secrets)
StripeJS.requestToken(secrets, @submit)
submit: =>
$rootScope.$apply ->
Loading.clear()
Navigation.go '/account'
full_name: (secrets) ->
secrets.first_name + " " + secrets.last_name

View File

@@ -0,0 +1,18 @@
Darkswarm.factory "Dates", ->
new class Dates
months: [
{key: t("january"), value: "1"},
{key: t("february"), value: "2"},
{key: t("march"), value: "3"},
{key: t("april"), value: "4"},
{key: t("may"), value: "5"},
{key: t("june"), value: "6"},
{key: t("july"), value: "7"},
{key: t("august"), value: "8"},
{key: t("september"), value: "9"},
{key: t("october"), value: "10"},
{key: t("november"), value: "11"},
{key: t("december"), value: "12"},
]
years: [moment().year()..(moment().year()+15)]

View File

@@ -1,7 +1,7 @@
Darkswarm.factory 'StripeJS', ($rootScope, Loading, RailsFlashLoader) ->
new class StripeJS
requestToken: (secrets, submit) ->
Loading.message = "Processing Payment..."
requestToken: (secrets, submit, loading_message = t("processing_payment")) ->
Loading.message = loading_message
params =
number: secrets.card_number
cvc: secrets.card_verification_value
@@ -13,7 +13,7 @@ Darkswarm.factory 'StripeJS', ($rootScope, Loading, RailsFlashLoader) ->
if response.error
$rootScope.$apply ->
Loading.clear()
RailsFlashLoader.loadFlash({error: "Error: #{response.error.message}"})
RailsFlashLoader.loadFlash({error: t("error") + ": #{response.error.message}"})
else
secrets.token = response['id']
secrets.cc_type = @mapCC(response.card.brand)

View File

@@ -2,4 +2,11 @@ Spree::UsersController.class_eval do
layout 'darkswarm'
before_filter :enable_embedded_shopfront
before_filter :set_credit_card, only: :show
private
def set_credit_card
@credit_card = Spree::CreditCard.new(user: @user)
end
end

View File

@@ -10,4 +10,6 @@ Spree::CreditCard.class_eval do
def has_payment_profile?
gateway_customer_profile_id.present? || gateway_payment_profile_id.present?
end
end

View File

@@ -2,12 +2,13 @@
.small-6.columns
%label
= t :first_name
%input{type: :text, disabled: true, "ng-value" => "order.bill_address.firstname"}
-# Changing name not permitted by default (in checkout) - can be enabled by setting an allow_name_change variable in $scope
%input{type: :text, "ng-disabled" => "!allow_name_change", "ng-value" => "order.bill_address.firstname"}
.small-6.columns
%label
= t :last_name
%input{type: :text, disabled: true, "ng-value" => "order.bill_address.lastname"}
%input{type: :text, "ng-disabled" => "!allow_name_change", "ng-value" => "order.bill_address.lastname"}
.small-6.columns
= validated_input t(:card_number), "secrets.card_number", "ng-required" => "!secrets.selected_card", maxlength: 19, autocomplete: "off", "ng-disabled" => "!!secrets.selected_card"

View File

@@ -1,5 +1,9 @@
.darkswarm
= inject_orders_by_distributor
= inject_saved_credit_cards
:javascript
Stripe.setPublishableKey("#{ENV['STRIPE_INSTANCE_PUBLISHABLE_KEY']}")
.row.pad-top
.small-12.columns.pad-top
@@ -9,6 +13,59 @@
= @user.email
(#{link_to t(:edit), spree.edit_account_path})
%h3
= t(:my_credit_cards)
.credit_cards{"ng-controller" => "CreditCardsCtrl"}
%h4
= t(:saved_cards)
.row
.card_list.small-12.columns
%span{"ng-repeat" => "card in savedCreditCards"}
%span{"ng-bind" => "card.formatted"}
%h4
= t(:add_new_credit_card)
.row
.new_card.small-12.columns
%form{novalidate: true, "ng-submit" => "storeCard()"}
-# render "spree/checkout/payment/gateway"
.row
.small-6.columns
%label
= t :first_name
-# Changing name not permitted by default (in checkout) - can be enabled by setting an allow_name_change variable in $scope
%input{type: :text, "ng-model" => "secrets.first_name","ng-disabled" => "!allow_name_change", "ng-value" => "order.bill_address.firstname"}
.small-6.columns
%label
= t :last_name
%input{type: :text, "ng-model" => "secrets.last_name", "ng-disabled" => "!allow_name_change", "ng-value" => "order.bill_address.lastname"}
.small-6.columns
%label
= t(:card_number)
%input{type: :text, "ng-model" => "secrets.card_number", "ng-required" => "!secrets.selected_card", maxlength: 19, autocomplete: "off", "ng-disabled" => "!!secrets.selected_card"}
.small-6.columns
%label
= t(:card_securitycode)
%input{type: :text, "ng-model" => "secrets.card_verification_value", "ng-required" => "!secrets.selected_card", autocomplete: "off", "ng-disabled" => "!!secrets.selected_card"}
.row
.small-12.columns
%label{for: "secrets.card_month"}
= t :card_expiry_date, "ng-disabled" => "!!secrets.selected_card"
.row
.small-6.columns
%select{"ng-model" => "secrets.card_month", "ng-options" => "currMonth.value as currMonth.key for currMonth in months", name: "secrets.card_month", "ng-required" => "!secrets.selected_card", "ng-disabled" => "!!secrets.selected_card"}
.small-6.columns
%select{"ng-model" => "secrets.card_year", "ng-options" => "year for year in years", name: "secrets.card_year", "ng-required" => "!secrets.selected_card", "ng-disabled" => "!!secrets.selected_card"}
%p
%button.button.primary{type: :submit}
= t :add_card
%h3= t(:my_orders)
.orders{"ng-controller" => "OrdersCtrl", "ng-cloak" => true}
.my-open-orders{ ng: { show: 'Orders.changeable_orders.length > 0' } }
%h3= t(:open_orders)