golang、php,laravel框架对接stripe海外支付接口的总结和流程(通俗易懂)

目录

stripe是什么?

环境

配置后台

首先让管理员把你设置成为开发者

然后进入后台

然后你要创建产品,开单周期要写每天,我这里理解成每天都会有人买的

获取产品id

获取密钥,后续代码需要用到

支付代码

唤起支付页面

测试的信用卡号

添加端点webhook

stripe后台配置

非常注意的地方

处理回调代码

golang代码(自己测试用的,go的程序员可以看看)

最后,怎么找到他们的技术支持呢?


stripe是什么?

我们国内有支付宝、微信、银联,国外就有stripe,但是他们是信用卡的。

据我探索,有以下支付方式

  1. Checkout Session 文档位置:https://docs.stripe.com/api/checkout/sessions
  2. payment links  文档位置: https://docs.stripe.com/api/payment_links/payment_links
  3. credit notes 文档位置:https://docs.stripe.com/api/credit_notes/object

注意:我们用checkout session

环境

PHP:7.2

框架:laravel 5.5以上都行

compose包:

composer require stripe/stripe-php

配置后台

我们在开始前,要清楚stripe的流程,他们的流程跟我们国内是完全不一样的。

首先让管理员把你设置成为开发者

然后进入后台

点产品目录,再点测试模式,在测试模式下,是不会产生付费的,都是虚拟的,大家可以放心

然后你要创建产品,开单周期要写每天,我这里理解成每天都会有人买的

获取产品id

获取密钥,后续代码需要用到

支付代码

#配置刚刚后台获取到的密钥
STRIPE_KEY=sk_test_5
use App\Http\Controllers\CIAesController;
use App\Http\Controllers\Controller;
use App\Model\OrdersModel;
use App\Model\ProductModel;
use App\Model\UsersModel;
use App\Model\VerifyCodesModel;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cookie;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Redirect;
use Stripe\Stripe;
use Stripe\StripeClient;//创建商品public function createProduct(Request $request){$vip_tag = $request->input('vip_tag');
//        $product_id  = 'prod_Q9V9Ypb6KFF4M4';
//        $order_id    = '29101d2d';
//        $goods_price = 1;try {$userInfo = $this->getUserInfoServer();if (!isset($userInfo['id']) || !$userInfo['id']) {throw new \Exception('当前未登录,请先登录', 9000);}if ($userInfo['type'] != 2) {throw new \Exception('请用邮箱登录再支付', 9000);}if ($userInfo['expiratio_date'] >= date('Y-m-d H:i:s')) {throw new \Exception('会员只支持购买一个');}$productInfo = ProductModel::where('vip_tag', $vip_tag)->first();if (!$productInfo) {throw new \Exception('暂无价格');}$product_id  = $productInfo->product_id;$order_id    = 'qw' . date('YmdHis') . time() . mt_rand(1000, 9999);$goods_price = $productInfo->price;// 创建订单OrdersModel::insert(['user_id'     => $userInfo['id'],'transfer_no' => $order_id,'amount'      => $goods_price,'product_id'  => $product_id,'status'      => 3,]);$url = $this->create_price($product_id, $order_id, $goods_price, 0);return Redirect::to($url);// 重定向去支付} catch (\Exception $e) {Log::error('createProduct', ['msg'  => $e->getMessage(),'file' => $e->getFile(),'line' => $e->getLine(),]);if ($e->getCode() == 9000) {return redirect('home/login');}return back()->withErrors([$e->getMessage()])->withInput();}}/**** 创建价格* @param $product_id 产品id* @param $order_id 业务系统的订单id* @param $goods_price* @param $is_source 订阅用到的* @return string|null* @throws \Stripe\Exception\ApiErrorException*/public function create_price($product_id, $order_id, $goods_price, $is_source){//获取订单对应的商品价格
//        $goods_price = \db('order')->where('id', $order_id)->value('pay_money');$_key      = env('STRIPE_KEY');// 你的私钥$stripe    = new StripeClient($_key);$price_arr = $stripe->prices->create(['unit_amount'  => $goods_price * 100,//'unit_amount' => 1*100,'currency'     => 'usd','tax_behavior' => 'exclusive',//'recurring' => ['interval' => 'day'],'product'      => $product_id,'metadata'     => ['order_id' => $order_id],]);//print_r($price_arr->id);die;return $this->actionStripe($price_arr->id, $order_id, $is_source);}/*** 创建stripe支付* @param $price_id 产品id* @param $order_id 业务系统订单id* @param $is_source 订阅用到的* @return string|null* @throws \Stripe\Exception\ApiErrorException*/public function actionStripe($price_id, $order_id, $is_source){$_key = env('STRIPE_KEY');$domain = 'xxx';// 要回调的域名//如果是AI订阅和AI作品打样的话if ($is_source == 8 || $is_source == 9) {$cancel_url  = '';$success_url = '';} else {$cancel_url  = $domain . '/home/actionNotify';$success_url = $domain . '/home/index';}// stripe 生成订单Stripe::setApiKey($_key);$checkout_session = \Stripe\Checkout\Session::create(['line_items'  => [['price'    => $price_id, // 产品id'quantity' => 1,],],'mode'        => 'payment','success_url' => $success_url,// 同步回调'cancel_url'  => $cancel_url,// 异步回调//            'automatic_tax' => [//                'enabled' => false,// 设置为true就要开通税务,会提示Stripe Tax has not been activated on your account. Please visit https://stripe.com/docs/tax/set-up to get started//            ],'metadata'    => ['order_id' => (string)$order_id,],]);Log::info('', ['ses' => $checkout_session, 'id' => $checkout_session->id]);return $checkout_session->url;}

唤起支付页面

当你调用完支付代码,会重定向到stripe支付界面

测试的信用卡号

因为我们是测试环境,这时候支付要用他们提供的测试信用卡号,那么这个卡号在哪里拿的呢?

点链接文档: https://docs.stripe.com/testing

stripe提供了好多信用卡给我们做测试的

添加端点webhook

这时候,我们创建完订单,如果用户支付完成,怎么回调呢?就比如我们支付宝、微信这些支付,都是要回调业务系统的订单号的

我们在上面的代码中,通过metadata来传递了订单号了,那么怎么接受他呢?没错,就是异步回调,stripe的异步回调叫做webhook

stripe后台配置

异步回调地址:http://xxxxx.com/home/actionNotify

非常注意的地方

一定要注意了我们用的是Checkout:Session方式

所以在添加webhook的时候,要选择checkout的,否则你会接受不到metadata元数据,这里面的订单号order_id

处理回调代码

public function actionNotify(Request $request){Log::info('asdas', ['all' => $request->all()]);$data = $request->input('data', []);$type = $request->input('type', '');$payload = @file_get_contents('php://input');try {if (!isset($data['object']) || !$data['object']) {throw new \Exception('参数有误');}$event = \Stripe\Event::constructFrom(json_decode($payload, true));switch ($event->type) {case 'checkout.session.completed':$succeeded = $event->data->object;$content = "=========".date('Y-m-d H:i:s',time())."==========\r\n";$content .= json_encode($succeeded);Log::info('content=======' . var_export($content, true));if ($succeeded->status == 'complete') {$order_id = $succeeded->metadata->order_id;// 处理支付成功逻辑$orderInfo = OrdersModel::where('status', 3)->where('transfer_no', $order_id)->first();try {if (!$orderInfo) {throw new \Exception('暂无订单');}$userInfo = UsersModel::where('status', 1)->where('id', $orderInfo->user_id)->first();if (!$userInfo) {throw new \Exception('没有此用户');}$productInfo = ProductModel::where('status', 1)->where('product_id', $orderInfo->product_id)->first();if (!$productInfo) {throw new \Exception('没有这个产品');}DB::beginTransaction();$productInfo->period = $productInfo->period + 1;$expiratio_date = date('Y-m-d', strtotime("+ $productInfo->period day"));$userBool       = UsersModel::where('id', $userInfo->id)->update(['expiratio_date'    => $expiratio_date,'day_search_number' => $productInfo->day_search_number + $userInfo->day_search_number,'vip_tag'           => $productInfo->vip_tag,]);if (!$userBool) {throw new \Exception('修改用户表失败');}$orderBool = OrdersModel::where('id', $orderInfo->id)->update(['status' => 1]);if (!$orderBool) {throw new \Exception('修改订单表失败');}DB::commit();} catch (\Exception $e) {DB::rollBack();Log::error('增加权限失败', ['msg'       => $e->getMessage(),'line'      => $e->getLine(),'file'      => $e->getFile(),'orderInfo' => $orderInfo,]);}}break;case 'checkout.session.async_payment_failed':Log::info('pay is failed');break;default:echo 'Received unknown event type ' . $event->type;break;}} catch(\UnexpectedValueException $e) {// Invalid payloadhttp_response_code(400);Log::error('actionNotify', ['msg'  => $e->getMessage(),'file' => $e->getFile(),'line' => $e->getLine(),'all'  => $request->all(),]);return false;}}

golang代码(自己测试用的,go的程序员可以看看)

package controllerimport ("fmt""github.com/gin-gonic/gin""github.com/stripe/stripe-go""github.com/stripe/stripe-go/checkout/session""log""os"
)func Stripe(c *gin.Context)  {stripe.Key = "sk_test_sxxxxxxx"lineItem := &stripe.CheckoutSessionLineItemParams{Quantity:     stripe.Int64(1),            // 数量Amount: stripe.Int64(100),Currency: stripe.String("usd"),Name: stripe.String("测试商品"),// 可以添加其他可选字段,比如 Description、Images 等}lineItems := []*stripe.CheckoutSessionLineItemParams{lineItem}params := &stripe.CheckoutSessionParams{SuccessURL: stripe.String("http://www.example.com/success"),CancelURL:  stripe.String("https://xxxxx.com/api/enterprise/wechat/mhCallback"),PaymentMethodTypes: stripe.StringSlice([]string{"card",}),Mode: stripe.String("payment"),LineItems: lineItems,}params.Metadata = map[string]string{"order_id":"123",}// 创建付款Sessions, err := session.New(params)if err != nil {log.Fatalf("Error creating Checkout Session: %v", err)}// 输出付款链接url := "https://checkout.stripe.com/c/pay/" + s.ID + "#fidkdWxOYHwnPyd1blpxYHZxWjA0VUJsMWhXdnxuN2p9SEBxYkltRkpGcn9GT2NAQHxcXDVGakFDYE9pdDFda3dXXHNwSUpDbzdkT2tmPGZmcEpIaURPU0JJdk89Yk13Nl9ddlVMV1c2TDM2NTUxclRuaEtydicpJ2N3amhWYHdzaaanP3F3cGApJ2lkfGpwcVF8dWAnPyd2bGtiaWBabHFgaCcpJ2BrZGdpYFVpZGZgbWppYWB3dic%2FcXxxYHgl"fmt.Fprintf(os.Stdout, "付款链接: %v\n", url)
return
}

最后,怎么找到他们的技术支持呢?

全程英文交流

文档位置:https://support.stripe.com/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/16704.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

摸鱼大数据——Hive表操作——基本操作

Hive表操作 Hive乱码解决 1、乱码现象 create database test1 comment "乱码测试"; use test1; CREATE TABLE orders ( orderId bigint COMMENT 订单id, orderNo string COMMENT 订单编号, shopId bigint COMMENT 门店id ); 2、处理步骤 注意&#…

Orange Pi AIpro——国产AI新星

初见香橙派AiPro 首先非常高兴能体验我们国产香橙派Aipro,在收到产品的时候还是被这精美的做工和强大的配置所折服。也为国内有这么多优秀的企业不断在进步和攀登而自豪。 比起我之前玩派的时候,同样的价格,现在给的实在是太多了&#xff…

前端JS必用工具【js-tool-big-box】学习,获取全球重点城市时间

我们去住一些旅馆的时候,或者一些国际性网站,经常可以看见他们的钟表会展示一些国家地区的时间,这个就是很常用的功能。但如果不常接触这个功能的开发网站呢,大家就看自己电脑右下角的时间展示,就是自己当前的具体时间…

新手一次过软考高级(系统规划与管理师)秘笈,请收藏!

2024上软考已经圆满结束,距离下半年的考试也只剩下半年不到的时间。需要备考下半年软考高级的小伙伴们可以抓紧开始准备了,毕竟高级科目的难度可是不低的。 今天给大家整理了——系统规划与管理师的备考资料 ,都是核心重点,有PDF&…

艾体宝洞察 | Redis Enterprise对比ElastiCache

选择缓存数据库时,如何在Amazon ElastiCache和Redis Enterprise之间做出选择,应当考虑哪些标准? ElastiCache 通常可以满足基本的缓存需求,因此是一种适合初始阶段的解决方案。但随着使用量的增加,ElastiCache很快会变…

OrangePi AIpro上手初体验:

OrangePi AIpro上手初体验: 1.基本外观及功能接口简介2.点亮OrangePi AIpro开发板3.OrangePi AIpro功能体验3.1.目标检测3.2.OCR文字识别3.3.图像的曝光增强3.4.系统的整体性能(运行ROS) 4.OrangePi AIpro体验总结4.1.硬件及软件生态:4.2.使用体验及性能…

数据结构(三)循环链表

文章目录 一、循环链表(一)概念(二)示意图(三)操作1. 创建循环链表(1)函数声明(2)注意点(3)代码实现 2. 插入(头插&#x…

【LeetCode刷题】滑动窗口解决问题:水果成篮、找到字符串中所有字母异位词

【LeetCode刷题】Day 9 题目1:904. 水果成篮思路分析:思路1:暴力枚举哈希表思路2:窗口滑动哈希表 题目2:438. 找到字符串中所有字母异位词思路分析:思路1:暴力枚举哈希表思路2:滑动窗…

极简编程:一行JS代码获取全球各城市当前时间!

之前在一些国际化网站看到过,他们展示了当前北京、纽约和伦敦的时钟,在一次住店的时候,我也看到了类似的3个时钟,甚至更多,有的会展示东京时间。 让我觉得获取一些全球重点城市的当前时间,会是一个很常用的…

【NumPy】关于numpy.add()函数,看这一篇文章就够了

🧑 博主简介:阿里巴巴嵌入式技术专家,深耕嵌入式人工智能领域,具备多年的嵌入式硬件产品研发管理经验。 📒 博客介绍:分享嵌入式开发领域的相关知识、经验、思考和感悟,欢迎关注。提供嵌入式方向…

5.4 Go 匿名函数与闭包

💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

网站笔记:huggingface——can you run it?

Can You Run It? LLM version - a Hugging Face Space by Vokturz 1 配置设置部分 Model Name就是需要测量的模型名称 GPU Vendor ——GPU供应商 Filter by RAM (按RAM过滤) 筛选出所有内存容量在选择范围之间的GPU GPU 下拉菜单选择具体的GPU型号 LoRa % trainable param…

靠AI创意,变现20w!

文章首发于公众号:X小鹿AI副业 大家好,我是程序员X小鹿,前互联网大厂程序员,自由职业2年,也一名 AIGC 爱好者,持续分享更多前沿的「AI 工具」和「AI副业玩法」,欢迎一起交流~ 之前X小鹿一直在各…

记录一次安装k8s初始化失败

实例化 kubeadm init --configkubeadm.yaml --ignore-preflight-errorsSystemVerification报错 [init] Using Kubernetes version: v1.25.0 [preflight] Running pre-flight checks error execution phase preflight: [preflight] Some fatal errors occurred:[ERROR CRI]: co…

海外仓erp系统是什么?和海外仓管理系统一样吗?

为了满足海外仓全球化发展的大趋势,同时提升海外仓运转的效率,一套好用,性价比高的海外仓管理系统还是非常重要的。 不过很多海外仓企业其实不太分得清erp系统和海外仓管理系统的差异,今天我们就来系统的聊一下,方便大…

K8S有了Service,为什么还要Ingress?

1、有了Service为什么还要Ingress? NodePort对外暴露端口存在的不足: 一个端口只能一个服务使用, 端口需要提前规划。 随着业务扩展, 端口的管理将是一个头疼的问题 只支持4层的负载均衡 LoadBalancer存在的不足: 贵、贵、贵。 要上云(俗话说上云…

需求跟踪矩阵是什么?怎么创建?一文详解

一、什么是需求跟踪矩阵 对项目经理或产品经理来说,需求清单肯定不陌生,那什么是需求跟踪矩阵呢? 需求跟踪矩阵(Requirement Track Matrix,简称RTM ),是把产品需求从其来源连接到能满足需求的…

无人机助力光伏项目测绘建模

随着全球对可再生能源需求的不断增长,光伏项目作为其中的重要一环,其建设规模和速度都在不断提高。在这一背景下,如何高效、准确地完成光伏项目的测绘与建模工作,成为了行业发展的重要课题。近年来,无人机技术的快速发…

哪个品种能够叫板白银现货t+d?

白银TD是在上海黄金交易所挂牌的白银投资品种,它可以说是国内版的现货白银交易,大家也可以把它理解成为白银交易的“快速通道”。通过它,投资者可以更加灵活地买卖白银,实现对内地白银价格的跟踪,并获得一定的杠杆化收…

git工作流程

以财务开发为例子: 1. 新建分支 1.1. upstream新建分支:finance-feature 1.2. origin新建对应分支:finance-feature 1.3 新建本地分支 git branch finance-feature 注: 同步远程分支:git fetch upstream feature…