Adding live stripe account status display to payment method create/edit interface

This commit is contained in:
Rob Harrington
2017-02-20 13:34:27 +11:00
parent f87f4310f0
commit 5ad88f992c
8 changed files with 180 additions and 26 deletions

View File

@@ -1,2 +1,18 @@
angular.module("admin.paymentMethods").controller "StripeController", ($scope, shops) ->
angular.module("admin.paymentMethods").controller "StripeController", ($scope, $http, shops) ->
$scope.shops = shops
$scope.stripe_account = {}
$scope.$watch "paymentMethod.preferred_enterprise_id", (newID, oldID) ->
return unless newID?
$scope.stripe_account = {}
$http.get("/admin/enterprises/#{newID}/stripe_account.json").success (data) ->
angular.extend($scope.stripe_account, data)
.error (response) ->
$scope.stripe_account.status = "request_failed"
$scope.current_enterprise_stripe_path = ->
return unless $scope.paymentMethod.preferred_enterprise_id?
permalink = shops.filter((shop) ->
shop.id == $scope.paymentMethod.preferred_enterprise_id
)[0].permalink
"/admin/enterprises/#{permalink}/edit#stripe"

View File

@@ -0,0 +1,80 @@
@import "../../darkswarm/mixins";
.alert-box {
position: relative;
display: block;
background-color: #eff5dc;
border: 1px solid #9fc820;
color: #666;
margin-top: 1em;
margin-bottom: 1em;
@include border-radius(3px);
transition: opacity 300ms ease-out;
padding: 0.77778em 1.33333em 0.77778em 0.77778em;
a.close {
position: absolute;
right: 5px;
top: 5px;
font-size: 1.5em;
}
&.ok {
border: 1px solid #9fc820;
background-color: #fbffee;
color: #9fc820;
font-weight: bold;
a.button {
padding: 3px 10px;
background-color: #a7c44d;
&:hover {
background-color: #9fc820;
}
}
a.close {
color: #9fc820;
}
}
&.error {
border: 1px solid #c82020;
background-color: #f5dcdc;
color: #c82020;
font-weight: bold;
a.button {
padding: 3px 10px;
background-color: #c85252;
&:hover {
background-color: #c82020;
}
}
a.close {
color: #c82020;
}
}
&.warning {
border: 1px solid #e6912e;
background-color: #fff4e6;
color: #e6912e;
font-weight: bold;
a.button {
padding: 3px 10px;
background-color: #db9350;
&:hover {
background-color: #e6912e;
}
}
a.close {
color: #e6912e;
}
}
}

View File

@@ -1,27 +1,5 @@
@import "../darkswarm/mixins";
.alert-box {
position: relative;
display: block;
background-color: #eff5dc;
border: 1px solid #9fc820;
color: #666;
margin-top: 1em;
margin-bottom: 1em;
@include border-radius(3px);
transition: opacity 300ms ease-out;
padding: 0.77778em 1.33333em 0.77778em 0.77778em;
a.close {
position: absolute;
right: 5px;
top: 0px;
font-size: 1.5em;
}
}
.dashboard_item.single-ent {
.header {
padding: 0.77778em 1.33333em 0.77778em 0.77778em;

View File

@@ -1,7 +1,7 @@
/ replace "div[data-hook='admin_payment_method_form_fields']"
= admin_inject_payment_method
= admin_inject_json_ams_array "admin.paymentMethods", "shops", @hubs, Api::Admin::IdNameSerializer
= admin_inject_json_ams_array "admin.paymentMethods", "shops", @hubs, Api::Admin::BasicEnterpriseSerializer
%div.alpha.eleven.columns{ "ng-app" => "admin.paymentMethods", "ng-controller" => "paymentMethodCtrl" }
.row
.alpha.three.columns

View File

@@ -1,4 +1,4 @@
class Api::Admin::BasicEnterpriseSerializer < ActiveModel::Serializer
attributes :name, :id, :is_primary_producer, :is_distributor, :sells, :category, :payment_method_ids, :shipping_method_ids
attributes :producer_profile_only
attributes :producer_profile_only, :permalink
end

View File

@@ -5,7 +5,38 @@
= fields_for :payment_method, @payment_method do |payment_method_form|
= payment_method_form.label :stripe_account_owner
%br
-# = payment_method_form.collection_select(:preferred_enterprise_id, @hubs, :id, :name, {:include_blank => true}, {:class => "select2 fullwidth"})
%input.ofn-select2.fullwidth#payment_method_preferred_enterprise_id{ type: 'number',
name: 'payment_method[preferred_enterprise_id]',
placeholder: t(".enterprise_select_placeholder"),
data: 'shops', ng: { model: 'paymentMethod.preferred_enterprise_id' } }
#stripe-account-status{ ng: { show: "paymentMethod.preferred_enterprise_id" } }
.alert-box.warning{ ng: { hide: "stripe_account.status" } }
= t(".loading_account_information_msg")
.alert-box.error{ ng: { show: "stripe_account.status == 'request_failed'" } }
= t(".request_failed_msg")
.alert-box.error{ ng: { show: "stripe_account.status == 'account_missing'" } }
= t(".account_missing_msg")
%a.button{ ng: { href: "{{current_enterprise_stripe_path()}}" }, target: 'blank' }
= t(".connect_one")
%i.icon-chevron-right
.alert-box.error{ ng: { show: "stripe_account.status == 'access_revoked'" } }
= t(".access_revoked_msg")
.alert-box.ok{ ng: { show: "stripe_account.status == 'connected'" } }
.status
%strong= t(".status") + ":"
= t(".connected")
%i.icon-ok
.account_id
%strong= t(".account_id") + ":"
{{ stripe_account.id }}
.business_name
%strong= t(".business_name") + ":"
{{ stripe_account.business_name }}
.charges_enabled
%strong= t(".charges_enabled") + ":"
{{ stripe_account.charges_enabled ? "say_yes" : "say_no" | t }}

View File

@@ -657,6 +657,7 @@ en:
producer_properties:
index:
title: Producer Properties
shared:
user_guide_link:
user_guide: User Guide
@@ -2060,6 +2061,19 @@ Please follow the instructions there to make your enterprise visible on the Open
one: "You have one active order cycle."
other: "You have %{count} active order cycles."
manage_order_cycles: "MANAGE ORDER CYCLES"
payment_methods:
stripe_connect:
enterprise_select_placeholder: Choose...
loading_account_information_msg: Loading account information from stripe, please wait...
request_failed_msg: Sorry. Something went wrong when trying to verify account details with Stripe...
account_missing_msg: No Stripe account exists for this enterprise.
connect_one: Connect One
access_revoked_msg: Access to this Stripe account has been revoked, please reconnect your account.
status: Status
connected: Connected
account_id: Account ID
business_name: Business Name
charges_enabled: Charges Enabled
products:
new:
title: 'New Product'

View File

@@ -29,6 +29,41 @@ feature %q{
payment_method = Spree::PaymentMethod.find_by_name('Cheque payment method')
payment_method.distributors.should == [@distributors[0]]
end
context "using stripe connect" do
let(:user) { create(:user, enterprise_limit: 5) }
let!(:connected_enterprise) { create(:distributor_enterprise, name: "Connected", owner: user) }
let!(:revoked_account_enterprise) { create(:distributor_enterprise, name: "Revoked", owner: user) }
let!(:missing_account_enterprise) { create(:distributor_enterprise, name: "Missing", owner: user) }
let!(:valid_stripe_account) { create(:stripe_account, enterprise: connected_enterprise, stripe_user_id: "acc_connected123") }
let!(:disconnected_stripe_account) { create(:stripe_account, enterprise: revoked_account_enterprise, stripe_user_id: "acc_revoked123") }
let!(:stripe_account_mock) { { id: "acc_connected123", business_name: "My Org", charges_enabled: true } }
before do
Stripe.api_key = "sk_test_12345"
stub_request(:get, "https://api.stripe.com/v1/accounts/acc_connected123").to_return(body: JSON.generate(stripe_account_mock))
stub_request(:get, "https://api.stripe.com/v1/accounts/acc_revoked123").to_return(status: 404)
end
it "communicates the status of the stripe connection to the user" do
login_as user
visit spree.new_admin_payment_method_path
select2_select "Stripe", from: "payment_method_type"
select2_select "Missing", from: "payment_method_preferred_enterprise_id"
expect(page).to have_selector "#stripe-account-status .alert-box.error", text: I18n.t("spree.admin.payment_methods.stripe_connect.account_missing_msg")
select2_select "Revoked", from: "payment_method_preferred_enterprise_id"
expect(page).to have_selector "#stripe-account-status .alert-box.error", text: I18n.t("spree.admin.payment_methods.stripe_connect.access_revoked_msg")
select2_select "Connected", from: "payment_method_preferred_enterprise_id"
expect(page).to have_selector "#stripe-account-status .status", text: "Status: Connected"
expect(page).to have_selector "#stripe-account-status .account_id", text: "Account ID: acc_connected123"
expect(page).to have_selector "#stripe-account-status .business_name", text: "Business Name: My Org"
expect(page).to have_selector "#stripe-account-status .charges_enabled", text: "Charges Enabled: Yes"
end
end
end
scenario "updating a payment method", js: true do