Rails:Paypal 端点 /v2/checkout/orders 返回 http 401
Posted
技术标签:
【中文标题】Rails:Paypal 端点 /v2/checkout/orders 返回 http 401【英文标题】:Rails: Paypal endpoint /v2/checkout/orders returns http 401 【发布时间】:2021-08-03 06:38:57 【问题描述】:此 paypal 结帐代码在 localhost 沙箱上完美运行,但在 Heroku 上失败并显示 401。当用户单击 Paypal 按钮时,会显示一个弹出式登录窗口并点击后端控制器 /orders/create_order .
前端 JS
<script src="https://www.paypal.com/sdk/js?client-id=<%=@client_id%>"></script>
<script>
paypal.Buttons(
env: '<%= @env %>', // Valid values are sandbox and live.
createOrder: async () =>
const config =
method: 'POST',
headers:
'Accept': 'application/json',
'Content-Type': 'application/json'
,
body: JSON.stringify(key: '<%= @order.key %>')
const response = await fetch('/orders/create_order', config);
const responseData = await response.json();
return responseData.token;
,
onApprove: async (data) =>
const response = await fetch('/orders/capture_order',
method: 'POST',
headers:
'Accept': 'application/json',
'Content-Type': 'application/json'
,
body: JSON.stringify(token: data.orderID)
);
const responseData = await response.json();
if (responseData.status === 'COMPLETED')
alert('Payment success!');
location.reload();
).render('#paypal-button-container');
</script>
后端 Rails 控制器
before_action :paypal_init
def paypal_init
@env = ENV["PAYPAL_ENV"]
@client_id = ENV["PAYPAL_CLIENT_ID"]
client_secret = ENV["PAYPAL_CLIENT_SECRET"]
environment = PayPal::SandboxEnvironment.new @client_id, client_secret
@client = PayPal::PayPalHttpClient.new environment
end
def create_order
ky = params[:key]
order = Order.where(key:ky).first
request = PayPalCheckoutSdk::Orders::OrdersCreateRequest::new
encoded = Base64.strict_encode64("#ENV["PAYPAL_CLIENT_ID"]:#ENV["PAYPAL_CLIENT_SECRET"]")
request.headers["Authorization"] = "Basic #encoded"
request.request_body(
:intent => 'CAPTURE',
:purchase_units => [
:amount =>
:currency_code => 'USD',
:value => order.price.to_s
]
)
begin
response = @client.execute(request)
result = response.result
order.token = result.id
if order.save!
return render :json => :token => order.token, :status => :ok
end
rescue PayPalHttp::HttpError => ioe
puts ioe.status_code
puts ioe.headers["debug_id"]
end
end
在请求对象上执行puts
会得到这个
"headers":"Content-Type":"application/json","Authorization":"Basic somevalue","body":"intent":"CAPTURE","purchase_units":[ "amount":"currency_code":"USD","value":"10"],"verb":"POST","path":"/v2/checkout/orders?"
我的尝试
我已经检查了 PAYPAL_CLIENT_ID 和 PAYPAL_CLIENT_SECRET 环境变量,它们使用了正确的生产值
我尝试在 Heroku 上将 PAYPAL_ENV 更改为 live 和 production
无数次重启 Heroku 应用
出于绝望尝试添加此行
request.headers["Authorization"] = "基本#encoded"
-
把我所有的指甲都嚼了
它不会停止返回 401,但可以在带有 Sandbox 的 localhost 上完美运行。
【问题讨论】:
【参考方案1】:环境 = PayPal::SandboxEnvironment.new @client_id, client_secret
如果您尝试使用生产客户端/秘密进行实时处理,这将是一个问题。
使 API 行为取决于您配置的 PAYPAL_ENV,而不是忽略它。
【讨论】:
【参考方案2】:通过检查 'sandbox' 或 'live' 的 env 变量更新我的代码,然后在我们不在沙箱中时初始化 LiveEnvironment
类
def paypal_init
@env = ENV["PAYPAL_ENV"]
@client_id = ENV["PAYPAL_CLIENT_ID"]
client_secret = ENV["PAYPAL_CLIENT_SECRET"]
if @env == 'sandbox'
environment = PayPal::SandboxEnvironment.new @client_id, client_secret
else
environment = PayPal::LiveEnvironment.new @client_id, client_secret
end
@client = PayPal::PayPalHttpClient.new environment
end
并删除了create_order
方法中的 Authorization 标头内容
encoded = Base64.strict_encode64("#ENV["PAYPAL_CLIENT_ID"]:#ENV["PAYPAL_CLIENT_SECRET"]")
request.headers["Authorization"] = "Basic #encoded"
现在可以了
【讨论】:
以上是关于Rails:Paypal 端点 /v2/checkout/orders 返回 http 401的主要内容,如果未能解决你的问题,请参考以下文章
PayPal SDK:PayPal 错误:找不到 live.dyson 的端点