LoginSignup
3
1

More than 3 years have passed since last update.

[Payjp] Payjp::InvalidRequestError No such tokenの解決法

Last updated at Posted at 2020-10-27

概要

Payjpでcustomerを作成しようとした際、No such tokenというエラーを解決するのに時間を要したため、解決した流れを記載しておきます。

エラーの内容

Image from Gyazo

上記のように、そのようなトークンはありませんと言われてしまいました。

  • トークンはJs→Rails側に送信できている
  • Completed 500 Internal Server Error

となっているため、サーバーサイド側のエラーだと思い、秘密鍵が合っているか等、色々試してみましたが解決できませんでした。

card.jsの記述

サーバーサイド側のエラーだと踏んでいたのですが、jsの記述も確認してみました。

card.js
const pay = () => {
  Payjp.setPublicKey(process.env.PAYJP_PUBLIC_KEY);
  const form = document.getElementById("charge-form");
  form.addEventListener("submit", (e) => {
    e.preventDefault();
    const formResult = document.getElementById("charge-form");
    const formData = new FormData(formResult);

    const card = {
      number: formData.get("number"),
      cvc: formData.get("cvc"), 
      exp_month: formData.get("exp_month"),
      exp_year: `20${formData.get("exp_year")}`
    };
    Payjp.createToken(card, (status, response) => {
      if (status === 200) {
        const token = response.id;
        const renderDom = document.getElementById("charge-form");
        const tokenObj = `<input value=${token}, type="hidden", name="card_token">`;
        renderDom.insertAdjacentHTML("beforeend", tokenObj);
       }
        document.getElementById("card-number").removeAttribute("name");
        document.getElementById("card-exp-month").removeAttribute("name");
        document.getElementById("card-exp-year").removeAttribute("name");
        document.getElementById("card-cvc").removeAttribute("name");

        document.getElementById("charge-form").submit();
        document.getElementById("charge-form").reset();
    });
  });
};
window.addEventListener("load", pay);

特におかしなところは無いように思えます・・・。

ある違和感

同じような記述で、jsを使って商品の合計金額(total_price)をサーバーサイドに送信するコードも書いていました。

sendTotalPrice.js
function sendTotalPrice() {
  const totalPriceDom = document.getElementById("cart-total-price")
  const totalPrice = parseInt(totalPriceDom.innerHTML);

  const renderDom = document.getElementById("charge-form");
  const totalPriceObj = `<input value=${totalPrice}, type="hidden", name="total_price">`;
  renderDom.insertAdjacentHTML("beforeend", totalPriceObj);
};
window.addEventListener('load', sendTotalPrice);

ここでおかしいと感じたことがあります。
Image from Gyazo
送信されたparamsのtotal_priceの中に
Image from Gyazo
不要な " , " が入ってしまっています。

原因はjs内の記述だった

トークンの値をフォームに含めるための記載に間違いがありました。

間違い
 const tokenObj = `<input value=${token}, type="hidden", name="card_token">`;
正しい
 const tokenObj = `<input value=${token} type="hidden" name="card_token">`;

value=${token}のあとのカンマ "," は不要でした!

勉強になったこと

Rails等のform_withなどでは属性を区切るためにカンマが必要ですが、HTML要素では属性を区切るカンマは不要ですね・・・。


同じような内容で悩まれている方がもしいらっしゃったら、参考になれば幸いです。

3
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
3
1