外贸独立站是做外贸的公司自己开设的独立品牌商城,主要区别于商城平台如亚马逊、阿里巴巴等,优点是自己的地盘自己说了算,缺点是需要自己推广引流,适合有一定品牌的商家。
大部分外贸公司都是两者都做,从商品平台推广获客,然后把流量引入自己的品牌商城,打造自己的私域流量商城。
Stripe支付公司是由一对来自爱尔兰的天才兄弟CollisonBrothers一手创办的,他们表示随着美国最大的民营金融科技公司进入小企业领域,新一轮融资使其价值增加了一半以上。
KlipC分析称,Stripe的商业模式主要是梳理目前有的支付方式,将不同的支付方式打包成一套SDK接口,通过整体接入,降低用户的接入成本,以收取手续费或者服务盈利。目前在金融行业,很多公司已经采用了Stripe的支付通道,比起传统通道,Stripe效率更高,成本更低。
第一步:安装类库
composerrequirestripe/stripe-ph
第二步后台控制器:
functioncreate(){
\Stripe\Stripe::setApiKey($this-clientSecret);//私钥
try{
$jsonStr=file_get_contents('php://input');
$jsonObj=json_decode($jsonStr);//获取页面参数
$arr=object_array($jsonObj);//转换为数组
$order_id=$arr['items'][0]['order_id'];//订单单号
$order=db('order')-where('order_id',$order_id)-find();//查找订单
//订单是否存在和支付状态
if(empty($order)){
echocan'tfindorder!;
exit();
}
if($order['pay_status']==20){
echo'Theorderwaspaid!';
exit();
}
$request=Request::instance();
$base_url=$request-domain();//获取网址
$time=time();
//判断支付订单是不是已经生成
if(!$order['stripe_pay']||$time-$order['stripe_time']30*60){
$currency_list=ExchangeRateModel::getFront();
$currency=$currency_list['code'];
$total_amount_currency=$order['pay_price'];
$paymentIntent=\Stripe\PaymentIntent::create([
'amount'=$total_amount_currency*100,//订单金额
'currency'=$currency,
'automatic_payment_methods'=[
'enabled'=true,
],
]);
$output=[
'clientSecret'=$paymentIntent-client_secret,
];
$transaction=explode('_secret_',$paymentIntent-client_secret);//记录生成的支付单号,单号后面会加单号_secret_安全码
$transaction_id=$transaction[0];
db('order')-where('order_id',$order_id)-update(['stripe_pay'=$paymentIntent-client_secret,'stripe_time'=$time,'transaction_id'=$transaction_id]);//记录单号
}else{
$output=[
'clientSecret'=$order['stripe_pay'],
];
}
//CreateaPaymentIntentwithamountandcurrency
echojson_encode($output);
}catch(Error$e){
http_response_code(500);
echojson_encode(['error'=$e-getMessage()]);
}
}
三,前端
inkrel=stylesheethref=__STATIC__/css/style.cssinkrel=stylesheethref=__STATIC__/css/checkout.cssscriptsrc=https://js.stripe.com/v3//script
script
varorder_id={$order_id}//订单号
varURL=/home/Stripepay
varkey={$key}
varbase_url={$base_url};
/script
scriptsrc=__STATIC__/js/checkout.jsdefer/script
formid=payment-form
pid=payment-element
!--Stripe.jsinjectsthePaymentElement--
/
buttonid=submit
pclass=spinnerhiddenid=spinner/
spanid=button-textPaynow/span
/button
pid=payment-messageclass=hidden/
/form
Checout.js
//ThisisyourtestpublishableAPIkey.
conststripe=Stripe(key);//公钥
//Theitemsthecustomerwantstobuy
constitems=[{id:xl-tshirt,order_id:order_id}];
etelements;initialize();
checkStatus();
document
.querySelector(#payment-form)
.addEventListener(submit,handleSubmit);
//Fetchesapaymentintentandcapturestheclientsecret
asyncfunctioninitialize(){
const{clientSecret}=awaitfetch(URL+/create,{
method:POST,
headers:{Content-Type:application/json},
body:JSON.stringify({items}),
}).then(res=res.json());
elements=stripe.elements({clientSecret});
constpaymentElement=elements.create(payment);
paymentElement.mount(#payment-element);
}
asyncfunctionhandleSubmit(e){
e.preventDefault();
setLoading(true);
console.log(elements);
const{error}=awaitstripe.confirmPayment({
elements,
confirmParams:{
//Makesuretochangethistoyourpaymentcompletionpage
return_url:base_url+URL+/successful.html,//成功后,回跳地址
},
});
//Thispointwillonlybereachedifthereisanimmediateerrorwhen
//confirmingthepayment.Otherwise,yourcustomerwillberedirectedto
//your`return_url`.ForsomepaymentmethodslikeiDEAL,yourcustomerwill
//beredirectedtoanintermediatesitefirsttoauthorizethepayment,then
//redirectedtothe`return_url`.
if(error.type===card_error||error.type===validation_error){
showMessage(error.message);
}else{
showMessage(Anunexpectederroroccured.);
}
setLoading(false);
}
//Fetchesthepaymentintentstatusafterpaymentsubmission
asyncfunctioncheckStatus(){
constclientSecret=newURLSearchParams(window.location.search).get(
payment_intent_client_secret
);
if(!clientSecret){
return;
}
const{paymentIntent}=awaitstripe.retrievePaymentIntent(clientSecret);
switch(paymentIntent.status){
casesucceeded:
showMessage(Paymentsucceeded!);
break;
caseprocessing:
showMessage(Yourpaymentisprocessing.);
break;
caserequires_payment_method:
showMessage(Yourpaymentwasnotsuccessful,pleasetryagain.);
break;
default:
showMessage(Somethingwentwrong.);
break;
}
}
//-------UIhelpers-------
functionshowMessage(messageText){
constmessageContainer=document.querySelector(#payment-message);
messageContainer.classList.remove(hidden);
messageContainer.textContent=messageText;
setTimeout(function(){
messageContainer.classList.add(hidden);
messageText.textContent=;
},4000);
}
//Showaspinneronpaymentsubmission
functionsetLoading(isLoading){
if(isLoading){
//Disablethebuttonandshowaspinner
document.querySelector(#submit).disabled=true;
document.querySelector(#spinner).classList.remove(hidden);
document.querySelector(#button-text).classList.add(hidden);
}else{
document.querySelector(#submit).disabled=false;
document.querySelector(#spinner).classList.add(hidden);
document.querySelector(#button-text).classList.remove(hidden);
}
}
在平台付款可以看到支付信息
四,获取支付状态:
webhooks添加回调地址和事件
charge.succeeded-支付成功后
需要密钥
五、获取回调信息,控制器
publicfunctioncallback()
{
$endpoint_secret='密钥';//;
$payload=@file_get_contents('php://input');
$sig_header=$_SERVER['HTTP_STRIPE_SIGNATURE'];
$event=null;
if($payload){
try{
$event=\Stripe\Webhook::constructEvent(
$payload,$sig_header,$endpoint_secret
);
}catch(\Stripe\Exception\SignatureVerificationException$e){
//Invalidsignature
http_response_code(400);
exit();
}
}
$log_name=notify_url.log;
$this-log_result($log_name,'pay-start|--'.$event-data-object-paymentIntent.'--|');
//Handletheevent
switch($event-type){
case'charge.succeeded':
$paymentIntent=$event-data-object;
//$payment=json_decode($paymentIntent);
$payID=$paymentIntent-payment_intent;
$order_no=db('order')-where('transaction_id',$payID)-value('order_no');
try{
$total_money=$event-amount/100;
//实例化订单模型
$model=$this-getOrderModel($order_no,10);
//订单信息
$order=$model-getOrderInfo();
if(empty($order)){
echo'Ordernotexist';
}
$update_data['transaction_id']=$payID;
$status=$model-onPaySuccess(20,$update_data);
$this-log_result($log_name,'order_no:'.$order_no.'pay|--'.$paymentIntent-payment_intent.'--|'.'status:'.$status);
if($status==false){
echo$model-getError();
}
}catch(Exception$e){
$this-error('PayError!','home/member/order');
//echo$e.',支付失败,支付ID【'.$paymentId.'】,支付人ID【'.$PayerID.'】';
//exit();
}
break;
case'charge.attached':
$paymentMethod=$event-data-object;
$this-log_result($log_name,'pay-attached|--'.$event-type.'--|');
break;
//...handleothereventtypes
default:
$this-log_result($log_name,'pay-fail|--'.$event-type.'--|');
echo'Receivedunknowneventtype'.$event-type;
}
}