#ruby-on-rails #ruby #devise #stripe-payments #stripe-connect
#ruby-on-rails #ruby #разработать #stripe-платежи #stripe-подключение
Вопрос:
Я создал одноранговую торговую площадку с использованием Stripe Connect для обработки платежей по кредитным картам с помощью stripe checkout и перевода этих платежей на подключенную учетную запись stripe с информацией об их банковском счете, и моя учетная запись будет взимать комиссию.
Мой код ранее работал в режиме разработки, но как только я отправил его в heroku, я получаю сообщение об ошибке после отправки платежа через stripe checkout.
Это текущая ошибка, которую я обнаруживаю при запуске журналов heroku…
Stripe::ошибка аутентификации (предоставленный ключ ‘sk_live_******************** 3yOZ’ не имеет доступа к учетной записи ‘ca_******************* 1LR1’ (или эта учетная запись не существует). Возможно, доступ к приложению был отозван.):
Вот мой спагетти-код… (Примечание: я просто воин выходного дня в Rails… удивительно, что я зашел так далеко, не имея никакого опыта программирования.)
Контроллер заказов
class OrdersController < ApplicationController
before_action :set_order, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
def sales
@orders = Order.all.where(seller: current_user).order("created_at DESC")
end
def purchases
@orders = Order.all.where(buyer: current_user).order("created_at DESC")
end
# GET /orders/new
def new
@order = Order.new
@item = Item.find(params[:item_id])
end
# POST /orders
# POST /orders.json
def create
@order = Order.new(order_params)
@item = Item.find(params[:item_id])
@seller = @item.user
@order.item_id = @item.id
@order.buyer_id = current_user.id
@order.seller_id = @seller.id
token = params[:stripeToken]
begin
customer = Stripe::Customer.create(
:email => params[:stripeEmail],
:source => token
)
require 'json'
charge = Stripe::Charge.create({
:customer => customer.id,
:amount => (@item.price * 91.1).floor - 30,
:currency => "usd",
:description => @item.title,
:application_fee => ((@item.price * 100) * 0.089).floor 30
},
{:stripe_account => ENV["STRIPE_CONNECT_CLIENT_ID"] }
)
@order.name = params[:stripeShippingName]
@order.address = params[:stripeShippingAddressLine1]
@order.city = params[:stripeShippingAddressCity]
@order.state = params[:stripeShippingAddressState]
@order.zip = params[:stripeShippingAddressZip]
@order.country = params[:stripeShippingAddressCountry]
flash[:notice] = "Thanks for ordering!"
rescue Stripe::CardError => e
flash[:danger] = e.message
redirect_to new_order_path
end
respond_to do |format|
if @order.save
format.html { redirect_to root_url }
format.json { render :show, status: :created, location: @order }
else
flash[:alert] = "Something went wrong :("
# gon.client_token = generate_client_token
format.html { render :new }
format.json { render json: @order.errors, status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_order
@order = Order.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def order_params
if params[:orders] amp;amp; params[:orders][:stripe_card_token].present?
params.require(:orders).permit(:stripe_card_token)
end
end
end
Контроллер обратных вызовов OmniAuth
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def stripe_connect
@user = current_user
if @user.update_attributes({
provider: request.env["omniauth.auth"].provider,
uid: request.env["omniauth.auth"].uid,
access_code: request.env["omniauth.auth"].credentials.token,
publishable_key: request.env["omniauth.auth"].info.stripe_publishable_key
})
# anything else you need to do in response..
sign_in_and_redirect @user, :event => :authentication
set_flash_message(:notice, :success, :kind => "Stripe") if is_navigational_format?
else
session["devise.stripe_connect_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
end
Сценарий Items Coffee (пользователь должен связать информацию о банковском счете с Stripe Connect перед перечислением)
jQuery ->
Stripe.setPublishableKey($('meta[name="stripe-key"]').attr('content'))
item.setupForm()
item =
setupForm: ->
$('#new_item').submit ->
$('input[type=submit]').attr('disabled', true)
Stripe.bankAccount.createToken($('#new_item'), item.handleStripeResponse)
false
handleStripeResponse: (status, response) ->
if status == 200
$('#new_item').append($('<input type="hidden" name="stripeToken" />').val(response.id))
$('#new_item')[0].submit()
else
$('#stripe_error').text(response.error.message).show()
$('input[type=submit]').attr('disabled', false)
Сценарий заказа кофе (Stripe будет обрабатывать информацию о карте при оформлении заказа)
jQuery ->
Stripe.setPublishableKey($('meta[name="stripe-key"]').attr('content'))
payment.setupForm()
payment =
setupForm: ->
$('#new_order').submit ->
$('input[type=submit]').attr('disabled', true)
Stripe.card.createToken($('#new_order'), payment.handleStripeResponse)
false
handleStripeResponse: (status, response) ->
if status == 200
$('#new_order').append($('<input type="hidden" name="stripeToken" />').val(response.id))
$('#new_order')[0].submit()
else
$('#stripe_error').text(response.error.message).show()
$('input[type=submit]').attr('disabled', false)
разработайте инициализатор.rb
config.omniauth :stripe_connect,
ENV['STRIPE_CONNECT_CLIENT_ID'],
ENV['STRIPE_SECRET_KEY'],
:scope => 'read_write',
:stripe_landing => 'register'
инициализатор stripe.rb
Rails.configuration.stripe = {
:publishable_key => ENV['STRIPE_PUBLISHABLE_KEY'],
:secret_key => ENV['STRIPE_SECRET_KEY']
}
Stripe.api_key = Rails.configuration.stripe[:secret_key]
application.yml (figaro) (ключи подвергнуты цензуре)
production:
STRIPE_SECRET_KEY: "sk_live_****************3yOZ"
STRIPE_PUBLISHABLE_KEY: "pk_live_******************HhWi"
STRIPE_CONNECT_CLIENT_ID: "ca_**********************1LR1"
CONNECTED_STRIPE_ACCOUNT_ID: "acct_***********crNm"
заказы _form.html.erb (только сценарий stripe)
<script src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="<%= Rails.configuration.stripe[:publishable_key] %>"
data-description="<%= @item.title %>"
data-amount="<%= (@item.price * 100).floor %>"
data-email="<%= current_user.email %>"
data-shipping-address="true"
data-locale="auto"></script>
Ответ №1:
Проблема здесь в том, что вы смешиваете свои константы. Всякий раз, когда вы делаете запрос API от имени подключенной учетной записи, вы хотите передать идентификатор подключенной учетной записи, acct_XXXYYYZZZ
, в Stripe-Account
заголовке.
Проблема здесь в том, что вместо этого вы передаете туда идентификатор клиента своей платформы ca_XXXX
. Затем Stripe пытается найти учетную запись с идентификатором ca_XXXX
, подключенным к вашей платформе, и она не существует.
Вам необходимо исправить код заряда, чтобы передать правильную константу:
charge = Stripe::Charge.create({
customer: customer.id,
amount: (@item.price * 91.1).floor - 30,
currency: 'usd',
description: @item.title,
application_fee: ((@item.price * 100) * 0.089).floor 30
},
{
stripe_account: ENV["CONNECTED_STRIPE_ACCOUNT_ID"]
}
)
Комментарии:
1. Как мне получить «CONNECTED_STRIPE_ACCOUNT_ID» этот идентификатор?
2. @AmanullahAman Это идентификатор подключенной учетной записи. Вы получаете его при создании учетной записи (пользовательской) или во время потока OAuth (стандартный и экспресс). Это выглядит так
acct_XXXXX
3. Спасибо @koopajah . Я понял.