简体   繁体   中英

You cannot accept payments using this API as it is no longer supported in India Next js, Strapi , Stripe

i am creating a website in "next.js" with the backend of "Strapi". This is a simple ecommerce type project. The payment gateway i am using is "Stripe". I included my code for checkout in both frontend and the backend and when i am using test mode in "Stripe" it is working well but when i am putting my real credentials there is showing an error.

{"error": {
"message": "You cannot accept payments using this API as it is no longer supported in India. Please refer to https://stripe.com/docs/payments for accepting payments.",
"type": "invalid_request_error"}}

I am confused why this is working fine in demo and not in real.

Below is my code:-

  1. My strapi backend
"use strict";

/**
 *  order controller
 */

const stripe = require("stripe")(
  "sk_test_my_test_code_from_stripe"
);



const { createCoreController } = require("@strapi/strapi").factories;



module.exports = createCoreController("api::order.order", ({ strapi }) => ({
  async create(ctx) {
    const {
      shippingAdress,
      city,
      state,
      amount,
      pin,
      mobile_number,
      name,
      token,
      items,
    } = ctx.request.body;

    await stripe.charges.create({
      amount: amount * 100,
      currency: "INR",
      source: token,
      description: `order by user ${ctx.state.user.email}`,
    });

    const order = await strapi.db.query("api::order.order").create({
      data: {
        shippingAdress,
        city,
        state,
        amount,
        pin,
        mobile_number,
        name,
        token,
        items,
        user: ctx.state.user.email,
      },
    });
    return order;
  },
}));


my next.js frontend

import React,{useState} from 'react'
import { useRouter } from 'next/router'
import {loadStripe} from '@stripe/stripe-js';
import {BACKEND_URL} from '../helper/baseUrl'
import {
  CardElement,
  Elements,
  useStripe,
  useElements,
} from '@stripe/react-stripe-js';
// import { strip } from 'jest-docblock';
import { useCart } from 'react-use-cart';
// import {BACKEND_URL} from '../helpers'
const stripePromise = loadStripe('pk_test_code_from_stripe');


const CheckoutForm = () => {
    const router = useRouter()
    const [formData,setFormData] = useState({})
    const [payProcessing,setPayProcessing] = useState(false)
    const [error,setError] = useState(false)
    const [done,setDone] = useState(false)


    const stripe = useStripe();
    const elements = useElements();
    const {cartTotal,items,emptyCart} = useCart()
    const [paybutton,setPayButton] = useState(true)
    //amount,shippingAddress,city,state,pin,token
    const handleChange = (e)=>{
        setFormData({
            ...formData,
            [e.target.name]:e.target.value
        })
    }

    
    const makePaymentRequest = async (allformData)=>{
        try{
            const res = await fetch(`${BACKEND_URL}/api/orders`,{
                method:"post",
                headers:{
                    "Content-Type":"application/json",
                    "Authorization":"Bearer "+localStorage.getItem("jwt")
                },
                body:JSON.stringify(allformData)
    
            })
            if(res.status != 200) throw Error('Payment failed')
            return await res.json()
        }catch(err){
            console.log(err)
            setError(true)
        }

    }
    const handleSubmit = async (event) => {
        event.preventDefault();
    
        if (elements == null) {
          return;
        }
       const cardElement = elements.getElement(CardElement)
       const payload = await stripe.createToken(cardElement)
     
       const allFormData = {
           ...formData,
           token:payload.token.id,
           amount:cartTotal,
           items:items
       }
        setPayProcessing(true)
        await makePaymentRequest(allFormData)
        setDone(true)
        setPayProcessing(false)
        emptyCart()

      };
    if(error) return <div className="text-center"> <h1 className="text-danger mt-5">Payment failed</h1></div>
    if(done) return <div className="text-center"><h1 className="text-success mt-5">Payment done successfully</h1> </div>
    // if(payProcessing) return <h1>Payment is processing...</h1>
    if(payProcessing)  return  <div className="text-center"> <h1 className="text-success mt-5">Wait, Processing Your Payment</h1> </div>
    return (
        <form className='mt-5' onSubmit={handleSubmit}>
            <div className="mb-3">

            <input 
            type="text"
             name="shippingAdress"
             placeholder="Your Address"
             onChange={handleChange}
             className="form-control"
             required
            />
            </div>
            <div className="mb-3">
            <input 
             type="text"
             name="city"
             placeholder="City"
             onChange={handleChange}
             className="form-control"
             required
            />
            </div>
            <div className="mb-3">
            <input 
             type="text"
             name="state"
             placeholder="State"
             onChange={handleChange}
             className="form-control"
             required
            />
            </div>

            <div className="mb-3">

            <input 
             type="number"
             name="pin"
             placeholder="Pin Code"
             onChange={handleChange}
             className="form-control"
             required
             />
             </div>

             <div className="mb-3">
            <input 
             type="number"
             name="mobile_number"
             placeholder="Mobile Number"
             onChange={handleChange}
             className="form-control"
             required
            />
            </div>

            <div className="mb-3">
            <input 
             type="text"
             name="name"
             placeholder="Name"
             onChange={handleChange}
             className="form-control"
             required
            />
            </div>

            <CardElement onChange={(e)=>{
                if(e.complete){
                  setPayButton(false)
                }else{
                    setPayButton(true)
                }
            }} />
            <br />
            <div className="text-center">

            <button className="btn btn-success" style={{width:'40%'}} type="submit" disabled={(!stripe || !elements) || paybutton}>
                Pay Now
            </button>
            </div>
        </form>
    )
}

const Checkout = ()=>{
    return(
        <Elements stripe={stripePromise}>
         <CheckoutForm />
       </Elements>
    )
}



export default Checkout

my package.json


{
  "name": "project",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@apollo/client": "^3.5.5",
    "@auth0/nextjs-auth0": "^1.7.0",
    "@stripe/react-stripe-js": "^1.7.0",
    "@stripe/stripe-js": "^1.22.0",
    "aos": "^2.3.4",
    "graphql": "^16.3.0",
    "next": "12.0.9",
    "react": "17.0.2",
    "react-carousel-slider": "^2.0.13",
    "react-countup": "^6.1.1",
    "react-dom": "17.0.2",
    "react-image-gallery": "^1.2.7",
    "react-number-easing": "^1.0.2",
    "react-toastify": "^8.1.0",
    "react-use-cart": "^1.13.0",
    "tiny-slider": "^2.9.4"
  },
  "devDependencies": {
    "eslint": "8.7.0",
    "eslint-config-next": "12.0.9"
  }
}


As per latest RBI guidelines, Stripe has switched from Charges API to Payment Intent API. Use below API as per data:

Stripe::PaymentIntent.create(
  :customer => customer.id,
  :amount => params[:amount],
  :description => 'Rails Stripe transaction',
  :currency => 'usd',
)

It worked for me. Checkout Stripe API documentation here

It might be cause you're using charges API, which does not support 3d secure transactions.

Try to use payment intents API, it supports 3d secure transactions, it'll work.

However you'll get payment acknowledgment response through webhooks

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM