无法使用 v2 API 版本创建草稿 PayPal 发票

Unable to create draft PayPal invoice using v2 API version

我正在 Ruby Rails 应用程序中将 PayPal Invoicing 功能从 v1 升级到 v2(因为 v1 已弃用) .

由于没有官方 library/gem 支持 v2 发票,所以我决定按照这里的官方文档构建所有内容:https://developer.paypal.com/docs/api/invoicing/v2.

流程是这样的:

  1. 系统将根据ClientIDClientSecret

    得到一个access-token
  2. 从这个 access-token,我将生成一个新的 invoice_number 通过发送 curl 请求到:https://api.sandbox.paypal.com/v2/invoicing/generate-next-invoice-number

  3. 收到 invoice_number 后,我将发送 curl 请求以创建包含所有必需数据的草稿发票端点

    curl -v -X POST https://api.sandbox.paypal.com/v2/invoicing/invoice
    

我面临的问题是最后一点。我从创建发票草稿端点收到 201 created 响应,但端点没有返回完整的发票对象和发票 ID。

这是我得到的:

"201"
{"rel"=>"self", "href"=>"https://api.sandbox.paypal.com/v2/invoicing/invoices/INV2-Z3K7-Y79X-36EM-ZQX8", "method"=>"GET"}

如果您尝试打开此 link,您将看到:

{
  "name":"AUTHENTICATION_FAILURE",
  "message":"Authentication failed due to invalid authentication credentials or a missing Authorization header.",
  "links": [
    {
      "href":"https://developer.paypal.com/docs/api/overview/#error",
      "rel":"information_link"
    }
  ]
}

不确定我在这里遗漏了什么!

以下代码供参考:

require 'net/http'
require 'uri'
require 'json'

class PaypalInvoice
  def initialize order
    @order = order
    @client_id = ENV['PAYPAL_CLIENT_ID']
    @client_secret = ENV['PAYPAL_CLIENT_SECRET']
    @base_url = ENV['AD_PP_ENV'] == 'sandbox' ? 'https://api.sandbox.paypal.com' : 'https://api.paypal.com'
    @paypal_access_token_identifier = 'paypal_access_token'
    @request_id ||= SecureRandom.uuid
  end

  def create_draft_invoice
    raise "Paypal token not found" unless Rails.cache.exist?(@paypal_access_token_identifier)

    invoice_number = "#141"
    sleep 5
    try = 0

    uri = URI.parse(@base_url + "/v2/invoicing/invoices")
    request = Net::HTTP::Post.new(uri)
    request['X-PAYPAL-SANDBOX-EMAIL-ADDRESS'] = ENV['PAYPAL_CLIENT_EMAIL']
    request['Authorization'] = "Bearer #{Rails.cache.fetch(@paypal_access_token_identifier)['access_token']}"
    request['Content-Type'] = 'application/json'
    request['PayPal-Request-Id'] = @request_id.to_s

    request.body = JSON.dump({
      "detail" => get_detail(invoice_number),
      "invoicer" => get_invoicer,
      "primary_recipients" => get_primary_recipients,
      "items" => items_info,
      "configuration" => {
        "partial_payment" => {
          "allow_partial_payment" => false,
        },
        "allow_tip" => false,
        "tax_calculated_after_discount" => true,
        "tax_inclusive" => true
      }
    })

    req_options = {
      use_ssl: uri.scheme == "https",
    }

    response = Net::HTTP.start(uri.host, uri.port, req_options) do |http|
      http.request(request)
    end

    p 'method: create_draft_invoice. response: '
    p response.code
    p JSON.parse(response.body)

    raise "Paypal token expired" if response.code.to_s == '401'

  rescue RuntimeError => error
    p "#{error.to_s}"
    try += 1
    access_token_response_status = get_new_access_token
    retry if access_token_response_status.to_s == '200' and try <= 1
  end
end

这个:

{"rel"=>"self", "href"=>"https://api.sandbox.paypal.com/v2/invoicing/invoices/INV2-Z3K7-Y79X-36EM-ZQX8", "method"=>"GET"}

是 API 调用的端点,特别是 'Show invoice details':https://developer.paypal.com/docs/api/invoicing/v2/#invoices_get

在浏览器中加载它 w/o Authorization: Bearer <Access-Token> header 将得到 AUTHENTICATION_FAILURE.


Sandbox 中目前存在一个关于未确认电子邮件的错误,因此请确保您的 Sandbox 电子邮件 are confirmed