7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

RubyでPayPayのAPIを呼んでみる

Posted at

目的

PayPayのAPIをRubyで使いたいです。しかし公式のSDKはPython, Node, PHP, JavaしかないのでREST APIを叩くことにします。リファレンスはこちらです。APIキーの取得などはDeveloperサイトで確認してください。

プログラム

プログラムはNodeのSDKのコードを参考に作りました。リファレンスもかなり詳細に書いてあるので助かります。APIはQRコードの作成だけ実装してあります。

Gemfile
# frozen_string_literal: true

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

gem 'httpclient'
paypay.rb
require 'base64'
require 'json'
require 'openssl'
require 'securerandom'
require 'time'
require 'httpclient'

module PayPay
  PROD = 'api.paypay.ne.jp'
  STAGING = 'stg-api.sandbox.paypay.ne.jp'
  PERF_MODE = 'perf-api.paypay.ne.jp'

  class QrCodeCreateBuilder
    def initialize()
      @result = {
        amount: {
          amount: 0,
          currency: 'JPY',
        },
        orderItems: [],
        metadata: {},
        codeType: 'ORDER_QR',
        storeInfo: 'store',
        storeId: '1',
        terminalId: '1',
        requestedAt: Time.now.to_i,
        redirectUrl: 'https://paypay.ne.jp/',
        redirectType: 'WEB_LINK',
        isAuthorization: false,
        authorizationExpiry: Time.now.to_i + 60,
      }
    end

    def merchantPaymentId(uuid = nil)
      @result["merchantPaymentId"] = uuid.nil? ? SecureRandom::uuid : uuid
    end

    def addItem(name, category, quantity, product_id, unit_amount)
      item = {
        name: name,
        category: category,
        quantity: quantity,
        productId: product_id,
        unitPrice: {
          amound: unit_amount,
          currency: 'JPY',
        },
      }
      @result[:orderItems] << item
      @result[:amount][:amount] = @result[:amount][:amount] + quantity * unit_amount
    end

    def finish()
      @result
    end
  end

  class Client
    def initialize(api_key, api_secret, merchant_id, production_flag = false, pref_flag = false)
      @api_key = api_key
      @api_secret = api_secret
      @merchant_id = merchant_id
      @host_name = 'https://' + if pref_flag
        PERF_MODE
      elsif production_flag
        PROD
      else
        STAGING
      end
    end

    def qr_code_create(params)
      method = 'POST'
      url = '/v2/codes'
      opa, content_type = PayPay.calc(@api_key, @api_secret, url, method, params)
      client = HTTPClient.new()
      #client.debug_dev = STDOUT
      client.post(@host_name + url, params.to_json, {"Authorization" => opa, "X-ASSUME-MERCHANT" => @merchant_id, 'Content-Type' => content_type})
    end
  end

  def self.calc(api_key, api_secret, url, method, body)
    nonce = SecureRandom.alphanumeric(8)
    epoch = Time.now.to_i.to_s
    payload, content_type = if body.nil? || body == ""
      ['empty', 'empty']
    else
      content_type = 'application/json;charset=UTF-8;'
      [
        Base64.strict_encode64(
          OpenSSL::Digest::MD5.digest(
            content_type + body.to_json
          )
        ),
        content_type
      ]
    end
    hashed64 = Base64.strict_encode64(
      OpenSSL::HMAC.digest(
        'sha256',
        api_secret,
        [url, method, nonce, epoch, content_type, payload].join("\n")
      )
    )
    ["hmac OPA-Auth:#{[api_key, hashed64, nonce, epoch, payload].join(":")}", content_type]
  end
end
main.rb
require './paypay'

builder = PayPay::QrCodeCreateBuilder.new()
builder.merchantPaymentId()
builder.addItem("ame", "sugger", 1, "1", 1)

client = PayPay::Client.new(ENV['API_KEY'], ENV['API_SECRET'], '12345')
response = client.qr_code_create(builder.finish())
pp response

まとめ

当初RubyとPayPayでぐぐったら誰かサンプルくらい書いてるかと思ったけど全然書いて無くて涙目でした。リファレンスがちゃんとしているので実装しやすいREST APIだと思います。もしお仕事でちゃんと使うなら他のSDKと同等くらいにしてgemで公開しようかと思います。

7
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?