❶ 怎麼在微信上簽字啊
添加微信小旦碼程序好簽,然後就可以在微信文件上簽字了。下面介紹具體操作方法:
1、首先打開微姿攔信,然後點擊發現。
❷ Thinkphp5.1微信小程序支付
研究了好幾天,坑也遇到了,也網路了很久現在終於做完了,給大家分享出來,
我這個也是參考別人寫的。有不明白的朋友可以問我
public function unifiedorder($order_no, $openid, $total_fee, $attach, $order_id, $user_id){
// 當前時間
$time = time();
// 生成隨機字元串
$nonceStr = md5($time . $openid);
// API參數
$params = [
'appid' => $this->appid, //微信分配的小程序id
'attach' => $attach, //附加數據,在查詢API和支付通知中原樣返回,可作為自定義參數使用。
'body' => '會員卡', //募捐描述
'mch_id' => $this->mchid, //微信支付分配的商戶號
'nonce_str' => $nonceStr, //隨機字元串,32位以內
'notify_url' => $this->notify_url, // base_url() . 'notice.php?s=/task/notify/order/wxapp_id/'.$wxapp_id, // 非同步通知地址
'openid' => $openid, //用戶標識;trade_type=JSAPI,此參數必傳,用戶在橋枯商戶appid下的唯一標識。
'out_trade_no' => $order_no, 槐消碼 //商戶賬單號
'spbill_create_ip' => \request()->ip(), //終端IP;支持IPV4和IPV6兩種格式的IP地址。調用微信支付API的機器IP
'total_fee' => (int)$total_fee * 100, // 價格:單位分 // 價格:單位分
'trade_type' => 'JSAPI', //交易類型
];
// 生成簽名
$params['sign'] = $this->makeSign($params); //這個地方最坑,需要的是配置 1、appid和商戶號必須是綁定的狀態
// 請求API
$url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
$result = $this->post($url, $this->toXml($params));
$prepay = $this->fromXml($result);
//添加preapay_id
$data = [
'user_id' => $user_id,
'order_id'鉛哪 => $order_id,
'attach' => json_encode($attach),
'prepay_id' => $prepay['prepay_id'],
];
(new AppleWxPrepay())->addInfo($data);
// 請求失敗
if ($prepay['return_code'] === 'FAIL') {
return [API_CODE_NAME => 2000004, API_MSG_NAME => $prepay['return_msg']];
}
if ($prepay['result_code'] === 'FAIL') {
return [API_CODE_NAME => 2000004, API_MSG_NAME => $prepay['err_code_des']];
}
// 生成 nonce_str 供前端使用
$paySign = $this->makePaySign($params['nonce_str'], $prepay['prepay_id'], $time);
return [
'prepay_id' => $prepay['prepay_id'],
'nonceStr' => $nonceStr,
'timeStamp' => (string)$time,
'paySign' => $paySign
];
}
/**
* 生成簽名
* @param $values
* @return string 本函數不覆蓋sign成員變數,如要設置簽名需要調用SetSign方法賦值
*/
private function makeSign($values)
{
//簽名步驟一:按字典序排序參數
ksort($values);
$string = $this->toUrlParams($values);
//簽名步驟二:在string後加入KEY
$string = $string . '&key=' . $this->apikey;
//簽名步驟三:MD5加密
$string = md5($string);
//簽名步驟四:所有字元轉為大寫
$result = strtoupper($string);
return $result;
}
/**
* 格式化參數格式化成url參數
* @param $values
* @return string
*/
private function toUrlParams($values)
{
$buff = '';
foreach ($values as $k => $v) {
if ($k != 'sign' && $v != '' && !is_array($v)) {
$buff .= $k . '=' . $v . '&';
}
}
return trim($buff, '&');
}
/**
* 模擬POST請求
* @param $url
* @param array $data
* @param bool $useCert
* @param array $sslCert
* @return mixed
*/
public function post($url, $data = [], $useCert = false, $sslCert = [])
{
$header = [
'Content-type: application/json; charset=UTF8'
];
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_POST, TRUE);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
if ($useCert == true) {
// 設置證書:cert 與 key 分別屬於兩個.pem文件
curl_setopt($curl, CURLOPT_SSLCERTTYPE, 'PEM');
curl_setopt($curl, CURLOPT_SSLCERT, $sslCert['certPem']);
curl_setopt($curl, CURLOPT_SSLKEYTYPE, 'PEM');
curl_setopt($curl, CURLOPT_SSLKEY, $sslCert['keyPem']);
}
$result = curl_exec($curl);
curl_close($curl);
return $result;
}
/**
* 輸出xml字元
* @param $values
* @return bool|string
*/
private function toXml($values)
{
if (!is_array($values) || count($values) <= 0) {
return false;
}
$xml = "<xml>";
foreach ($values as $key => $val) {
if (is_numeric($val)) {
$xml .= "<" . $key . ">" . $val . "</" . $key . ">";
} else {
$xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
}
}
$xml .= "</xml>";
return $xml;
}
/**
* 將xml轉為array
* @param $xml
* @return mixed
*/
private function fromXml($xml)
{
// 禁止引用外部xml實體
libxml_disable_entity_loader(true);
return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
}
/**
* 生成paySign
* @param $nonceStr
* @param $prepay_id
* @param $timeStamp
* @return string
*/
private function makePaySign($nonceStr, $prepay_id, $timeStamp)
{
$data = [
'appId' => $this->appid,
'nonceStr' => $nonceStr,
'package' => 'prepay_id=' . $prepay_id,
'signType' => 'MD5',
'timeStamp' => $timeStamp,
];
// 簽名步驟一:按字典序排序參數
ksort($data);
$string = $this->toUrlParams($data);
// 簽名步驟二:在string後加入KEY
$string = $string . '&key=' . $this->apikey;
// 簽名步驟三:MD5加密
$string = md5($string);
// 簽名步驟四:所有字元轉為大寫
$result = strtoupper($string);
return $result;
}
/*********************************微信回調**********************/
public function getNotify()
{
if (!$xml = file_get_contents('php://input')) {
$this->returnCode(50000001, 'Not found DATA');
}
// 將伺服器返回的XML數據轉化為數組
$data = $this->fromXml($xml);
$payLog = new ApplePayLog();
// 記錄日誌
$payLog->addInfo(['content'=>json_encode($xml)]);
$payLog->addInfo(['content'=>json_encode($data)]);
// 實例化賬單模型
$OrderModel = new AppleOrder();
// 賬單信息
$orderInfo = $OrderModel->getInfo(['id'=>$data['attach']],'*');
if (empty($orderInfo)) {
$this->returnCode(50000001, '賬單不存在');
}
if($orderInfo['pay_status'] != 1 || !empty($orderInfo['pay_time'])){
$this->returnCode(50000001,'訂單已支付,請勿再次支付');
}
// 保存微信伺服器返回的簽名sign
$dataSign = $data['sign'];
$return_code = $data['return_code'];
$result_code = $data['result_code'];
$data['body'] = '會員卡';
$data['spbill_create_ip'] = \request()->ip();
$data['notify_url'] = $this->notify_url;
// sign 與 s 參數 不參與簽名演算法
unset($data['sign']);
unset($data['transaction_id']);
unset($data['coupon_id']);
unset($data['coupon_type']);
unset($data['coupon_count']);
unset($data['coupon_fee']);
unset($data['time_end']);
unset($data['return_code']);
unset($data['result_code']);
unset($data['is_subscribe']);
unset($data['fee_type']);
unset($data['bank_type']);
unset($data['bank_type']);
// 生成簽名
$sign = $this->makeSign($data);
// 判斷簽名是否正確 判斷支付狀態
if (($sign === $dataSign) && ($return_code == 'SUCCESS') && ($result_code == 'SUCCESS')) {
$OrderModel->startTrans();
try {
// 賬單支付成功業務處理
$appleOrderInfo = $OrderModel->where(['id'=>$orderInfo['id']])->lock(true)->find();
$result = $appleOrderInfo->addInfo(['pay_status'=>2,'pay_time'=>time()],['id'=>$orderInfo['id']]);
if(!$result){
$OrderModel->rollback();
$this->returnCode(5000003, '修改訂單失敗,失敗原因:'.$OrderModel->getError());
}
$appleUserModel = new AppleUser();
$appleUserInfo = $appleUserModel->where(['openid'=>$orderInfo['openid']])->lock(true)->find();
$appleUser = $appleUserInfo->where(['openid'=>$orderInfo['openid']])->setInc('moxibustion',$orderInfo['moxibustion']);
if(!$appleUser){
$OrderModel->rollback();
$this->returnCode(5000003, '添加會員針灸次數失敗,失敗原因:'.$appleUserModel->getError());
}
}catch (\Exception $exception){
$OrderModel->rollback();
$this->returnCode(5000003, '操作失敗,失敗原因:'.$exception->getMessage());
}
$OrderModel->commit();
// 返回狀態
die(json(['code'=>0,'支付成功']));
}
// 返回狀態
$this->returnCode(2000003, '簽名失敗');
}
❸ 微信小程序是什麼,能幹嘛,有什麼優勢
微信應用號是一個APP應用推廣平台,微信應用號目前暫定名為「小程序」,使用微信應用號平台,用戶關注一個應用號就如同安裝一個App一樣,而微信應用號就相當於另一個App Store,主要功能就是應用推廣。
用戶關注一個應用號就如同安裝一個App一樣,而微信應用號就相當於另一個App Store,主要功能就是應用推廣。微信的目的似乎很簡單,就是希望把用戶使用App的動作都集中在微信上。
應用號有兩大特色:首先APP功能可以直接通過關注應用號來實現,所以用戶就省去了安裝下載卸載等等一系列動作,對那些使用頻率不高的軟體來說,你完全可以用「應用號」代替;另外,用戶也免去了不定時下載軟體更新包的困擾。
然而微信應用號要能獲取足夠多的用戶,還得要開發者的支持。
毫無疑問,兄租虛開發者將是微信應用號的最大獲益群體。對於開發者而言,應用號可以節省開發成本,並且可以提升研發效率,開發人員只需要羨燃研發出一款適用於瀏覽器應用的產品,就可滿足不同操作系統的使用需求。另外,入駐應用號的APP營銷推廣工作也能取到事半功倍的效果。
微信應用號-小程序功能介紹
視圖容器:視圖(View)、滾動視圖、Swiper
基礎內容:圖標、文本、進度條
表單組件:按鈕、表單等等
操作反饋
導航
媒體組建:音頻、圖片、視頻。
地圖
畫布
文件操作能力
網路:上傳下載能力、WebSocket
數據:數據緩存能力
位置:獲取位置、查看位置
設備:網路狀態、系統信息、重力感應、羅盤
界面:設置導航條、導航、動畫、繪圖等等
開放介面:登錄,包括簽名加密,用戶信息、微信支付、模板消息
微信小程序平台特色
應用號目前的稱呼是「微信小程序」,而不是之前討論廣泛的應用號;介面和框架包括:視圖、內容、按鈕、導航、多媒體、網路能力、羅盤、重力感應、畫板等。
有了這個框架和豐富的組件,小程序的啟動和運行速度將可以和原生 app 媲美。能實現的功能也將被純網頁的服務號要多得多;小程序開發後,不能直接發布,需要經過審核,類似 App Store。
小程序是一種不需要下載安裝即可使用的應用,它實現了應用「觸手可及」的夢想,用戶掃一掃或者搜一下即可打開應用。也體現了「用完即走」的理念,用戶不用關心是否安裝太多應用的問題。應用將無處不在,隨時可用,但又無需安裝卸載。
微信應用號被認為是「跨平台的操作系統」,行業內反應熱烈,更多的擔心在於諸多App(移動端應用)將面臨沖擊,一位熟悉騰訊內部人士就此事表示,「其實都在說明一件事,真的不用開發 app 了。」
微信應用號被盛傳多時,而相比於app等,基於微信生態的應用號有著天然優勢。
一是微信有海量用戶,而且粘性很高,在微信里開發產品更容易觸達用戶;
二是推廣app 或公眾號的成本太高,而應用號「無需下載」的優勢能夠使用戶減少心理負擔,推廣效率更高。推廣微信應用號,只需要用戶掃碼即可,不管是流量環境還是WIFI環境,都不是問題,最大程度減少了用戶的耐心損耗。
三是微信除了能給用戶提供功能,還能推送內容,同時還會多出一個未讀標記。這種推送到達率比 app 更高。
四是開發適配成本低。微信公眾號開發涉及網頁前端和伺服器後端,相比起 iOS 和 Android 開發,至型態少節省了兩個平台的開發成本,節省了大量的時間和人力。因為開發這兩個平台的客戶端,伺服器後端的開發幾乎是必須有的,網頁前端可能相對微信公眾號要少一些,但相比之下,這些前端的工作比客戶端的工作量要少很多。
在微信應用里,不管用戶用的是何種手機,獲得的體驗是一致的。如果不一致,也能用相對較低的開發成本讓其一致。如果你開發的是一個微信消息應用,微信提供了固定的消息模板,這意味著,不管用戶使用的是什麼系統,他們看到的界面是相同的。
五是容易小規模試錯,然後快速迭代。這被認為是現今互聯網創業的基本方法。而且修改無需等待審核,迭代後馬上能看到效果,然後繼續觀察和迭代。
六是跨平台。微信應用號本身是網頁,可以在群里被轉發,可以搭建到公眾號上,傳播起來非常方便。
在這上面看到的http://www.mntuku.cn/index.php/article/show/id-520
❹ 微信小程序訂單如何退款
一. 支付
支付主要分為幾個步驟:
1前端攜帶支付需要的數據(商品id,購買數量等)發起支付請求
2後端在接收到支付請求後,處理支付數據,然後攜帶處理後的數據請求 微信伺服器 的 支付統一下單介面
3後端接收到上一步請求微信伺服器的返回數據,再次處理,然後返回前端讓前端可以開始支付。
4前端進行支付動作
5前端支付完成後,微信伺服器會向後端發送支付通知(也就是微信要告訴你客戶已經付過錢了),後端根據這個通知確定支付完成,然後就去做支付完成後的相應動作,比如修改訂單狀態,添加交易日誌啊等等。
從這幾個步驟可以看出,後端主要的作用就是將支付需要的數據傳給微信伺服器,再根據微信伺服器的響應確定支付是否完成。
這個流程還是蠻容易理解的。形象的說,前端就是個顧客,後端就是店家,微信伺服器的統一下單介面就像收銀員。顧客跟店家說,我是誰誰誰,現在我要付多少多少錢給你買什麼什麼。店家就跟收銀員說,那個誰誰誰要付多少錢,你准備收錢吧。收銀員收到錢後,就去告訴店家,我已經收到錢了,你給他東西吧。
下面就詳細的說明一下 各個步驟的具體實現。
1. 前端請求支付
前端請求支付,就是簡單的攜帶支付需要的數據,例如用戶標識,支付金額,支付訂單 ID 等等跟 **你的業務邏輯有關** 或者跟 **下一步請求微信伺服器支付統一下單介面需要的數據有關** 的相關數據,使用微信小程序的 wx.request( ) 去請求後端的支付介面。
2. 後端請求微信伺服器
後端接收到前端發送的支付請求後,可以進行一下相關驗證,例如判斷一下用戶有沒有問題,支付金額對不對等等。
在驗證沒什麼問題,可以向微信伺服器申請支付之後,後端需要使用 微信規定的數據格式 去請求微信的支付統一下單介面。
微信規定的請求數據:
這需要較多代碼實現。因為需要的數據個數較多,而且還需要加密並以 XML 格式發送。
首先,有以下數據是使用小程序支付必須提供給微信伺服器的參數。
小程序 appid。寫小程序的大概沒有不知道這個的。。。
用戶標識 openid。也就是用戶的小程序標識,在我上篇博客中說明了如何獲取。
商戶號 mch_id 。申請開通微信支付商戶認證成功後微信發給你的郵件里有
商戶訂單號 out_trade_no 。商戶為這次支付生成的訂單號
總金額 total_fee 。訂單總金額,很重要的一點是單位是分,要特別注意。
微信伺服器回調通知介面地址 notify_url。微信確認錢已經到賬後,會往這個地址多次發送消息,告訴你顧客已經付完錢了,你需要返回消息給微信表示你已經收到了通知。。這個地址不能有埠號,同時要能直接接受POST方法請求。
交易類型 trade_type 。微信小程序支付此值統一為 JSAPI
商品信息 Body。類似"騰訊-游戲"這種格式
終端IP地址 spbill_create_ip 。終端地址IP,也就是請求支付的 IP 地址。
隨機字元串 nonce_str 。需要後端隨機生成的字元串用於保證數據安全。微信要求不長於32位。
簽名 sign 。使用上面的所有參數進行相應處理加密生成簽名。(具體處理方式可見下文代碼,可直接復用。)
在處理好以上所有數據後,將這些數據以 XML 格式整理並以 POST 方法發送到 微信支付統一下單介面 https://api.mch.weixin.qq.com/pay/unifiedorder 。
3.後端接受微信伺服器返回數據
微信伺服器在接收到支付數據之後,如果數據沒有問題,其會返回用於支付的相應數據,其中非常重要的是 名稱為 prepay_id 的數據欄位,需要將此數據返回前端,前端才能繼續支付。
因此,在後端接收到微信伺服器的返回數據後,需要進行相應的處理,最終返回到前端如下數據:
appid 不需多說
timeStamp 當前時間戳
nonceStr 隨機字元串
package 就是上面提到的 prepay_id,不過切記格式如 「prepay_id= prepay_id_item「。否則會導致錯誤。
signType 加密方式,一般應該是 MD5
paySign 對以上數據進行相應處理並加密。
到這里,後端的支付介面已經完成了接收前端支付請求,並返回了前端支付所需數據的功能。
4. 前端發起支付
前端在接收到返回數據後,使用 wx.requestPayment() 來請求發起支付。此 API 需要的對象參數各項值就是我們上一步返回的各個數據。
5.後端接受微信伺服器回調
前端完成支付後,微信伺服器確認支付已經完成。就會向第一步中設置的回調地址發送通知。後端的接收回調介面在接收到通知後,就可以判斷支付是否完成,從而決定後續動作。
需要注意的是,在接收到微信伺服器的回調通知後,根據通知的result_code欄位判斷支付是否成功。在接受到成功的通知後,後端需要返回success數據向微信伺服器告知已得到回調通知。否則微信伺服器會不停的向後端發送消息。另外微信的通知是以XML格式發送的,在接受處理時需要注意。
微信的大概支付流程就是這樣。以下是PHP語法的微信支付類,可以比照上面的步驟介紹,加深理解。在需要支付時,直接傳入參數實例化此類再調用類的 pay 方法即可。
//微信支付類
class WeiXinPay{
//=======【基本信息設置】=====================================
//微信公眾號身份的唯一標識
protected $APPID = appid;//填寫您的appid。微信公眾平台里的
protected $APPSECRET = secret;
//受理商ID,身份標識
protected $MCHID = '11111111';//商戶id
//商戶支付密鑰Key
protected $KEY = '';
//回調通知介面
protected $APPURL = 'https://smart.afei.com/receivesuc';
//交易類型
protected $TRADETYPE = 'JSAPI';
//商品類型信息
protected $BODY = 'wx/book';
//微信支付類的構造函數
function __construct($openid,$outTradeNo,$totalFee){
$this->openid = $openid; //用戶唯一標識
$this->outTradeNo = $outTradeNo; //商品編號
$this->totalFee = $totalFee; //總價
}
//微信支付類向外暴露的支付介面
public function pay(){
$result = $this->weixinapp();
return $result;
}
//對微信統一下單介面返回的支付相關數據進行處理
private function weixinapp(){
$unifiedorder=$this->unifiedorder();
$parameters=array(
'appId'=>$this->APPID,//小程序ID
'timeStamp'=>''.time().'',//時間戳
'nonceStr'=>$this->createNoncestr(),//隨機串
'package'=>'prepay_id='.$unifiedorder['prepay_id'],//數據包
'signType'=>'MD5'//簽名方式
);
$parameters['paySign']=$this->getSign($parameters);
return $parameters;
}
/*
*請求微信統一下單介面
*/
private function unifiedorder(){
$parameters = array(
'appid' => $this->APPID,//小程序id
'mch_id'=> $this->MCHID,//商戶id
'spbill_create_ip'=>$_SERVER['REMOTE_ADDR'],//終端ip
'notify_url'=>$this->APPURL, //通知地址
'nonce_str'=> $this->createNoncestr(),//隨機字元串
'out_trade_no'=>$this->outTradeNo,//商戶訂單編號
'total_fee'=>floatval($this->totalFee), //總金額
'open_id'=>$this->openid,//用戶openid
'trade_type'=>$this->TRADETYPE,//交易類型
'body' =>$this->BODY, //商品信息
);
$parameters['sign'] = $this->getSign($parameters);
$xmlData = $this->arrayToXml($parameters);
$xml_result = $this->postXmlCurl($xmlData,'https://api.mch.weixin.qq.com/pay/unifiedorder',60);
$result = $this->xmlToArray($xml_result);
return $result;
}
//數組轉字元串方法
protected function arrayToXml($arr){
$xml = "<xml>";
foreach ($arr as $key=>$val)
{
if (is_numeric($val)){
$xml.="<".$key.">".$val."</".$key.">";
}else{
$xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
}
}
$xml.="</xml>";
return $xml;
}
protected function xmlToArray($xml){
$array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $array_data;
}
//發送xml請求方法
private static function postXmlCurl($xml, $url, $second = 30)
{
$ch = curl_init();
//設置超時
curl_setopt($ch, CURLOPT_TIMEOUT, $second);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); //嚴格校驗
//設置header
curl_setopt($ch, CURLOPT_HEADER, FALSE);
//要求結果為字元串且輸出到屏幕上
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
//post提交方式
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt($ch, CURLOPT_TIMEOUT, 40);
set_time_limit(0);
//運行curl
$data = curl_exec($ch);
//返回結果
if ($data) {
curl_close($ch);
return $data;
} else {
$error = curl_errno($ch);
curl_close($ch);
throw new WxPayException("curl出錯,錯誤碼:$error");
}
}
/*
* 對要發送到微信統一下單介面的數據進行簽名
*/
protected function getSign($Obj){
foreach ($Obj as $k => $v){
$Parameters[$k] = $v;
}
//簽名步驟一:按字典序排序參數
ksort($Parameters);
$String = $this->formatBizQueryParaMap($Parameters, false);
//簽名步驟二:在string後加入KEY
$String = $String."&key=".$this->KEY;
//簽名步驟三:MD5加密
$String = md5($String);
//簽名步驟四:所有字元轉為大寫
$result_ = strtoupper($String);
return $result_;
}
/*
*排序並格式化參數方法,簽名時需要使用
*/
protected function formatBizQueryParaMap($paraMap, $urlencode)
{
$buff = "";
ksort($paraMap);
foreach ($paraMap as $k => $v)
{
if($urlencode)
{
$v = urlencode($v);
}
//$buff .= strtolower($k) . "=" . $v . "&";
$buff .= $k . "=" . $v . "&";
}
$reqPar;
if (strlen($buff) > 0)
{
$reqPar = substr($buff, 0, strlen($buff)-1);
}
return $reqPar;
}
/*
* 生成隨機字元串方法
*/
protected function createNoncestr($length = 32 ){
$chars = "";
$str ="";
for ( $i = 0; $i < $length; $i++ ) {
$str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);
}
return $str;
}
}
以上就是微信支付的相關流程。在理清思路後,流程還是比較清晰和簡單的。重點在於需要注意一些細節問題,例如數據格式,加密方法等。
下面說一下微信小程序退款的具體實現
二.退款
小程序退款的流程和付款相似,但有一些細節上的不同。
首先退款的步驟通常如下:
1.用戶前端點擊退款按鈕後,後端接收到用戶的退款請求通過商城後台呈現給商戶,商戶確定允許退款後,後端再發起向微信退款介面的請求來請求退款。
2.後端向微信退款介面發送請求後,得到響應信息,確定退款是否完成,根據退款是否完成再去進行改變訂單狀態等業務邏輯。
退款的步驟相對微信支付來說比較簡單。
值得注意的有以下兩點:
1.向微信退款介面請求退款後,根據得到的響應是可以直接確定退款是否完成的。不再需要設置專門的回調介面等待微信通知。當然如果需要也是可以在微信商戶平台設置回調介面接受從而接受微信回調的,但並不是必須的。
2.退款請求需要在請求伺服器安裝微信提供的安全證書,也就是說,發起退款請求相比較支付請求在請求時請求方法不能復用,因為微信退款需要攜帶證書的請求,此證書可在申請微信商戶號成功後從微信商戶平台自行下載, Linux下的PHP開發環境的證書只需要放在網站根目錄的cert文件夾中即可。其他開發環境可能需要導入操作。
下面講解一下退款的具體步驟
一. 用戶發起退款請求
用戶在前端發起退款請求,後端接收到退款請求,將相應訂單標記為申請退款,展示在後台.商戶查看後,如果同意退款再進行相應操作.此後才進入真正的退款流程.
二. 商戶發起退款請求
商戶同意退款後,後端即向微信提供的退款 API 發起請求.
同請求微信支付API一樣.退款請求也需要將需要的參數進行簽名後以XML發送到微信的退款API [https://api.mch.weixin.qq.com/pay/refund](https://api.mch.weixin.qq.com/pay/refund)
退款請求需要的參數如下(多個參數在支付API請求時也有使用):
1.小程序 appid。
2.商戶號 mch_id 。申請開通微信支付商戶認證成功後微信發給你的郵件里有
3.商戶訂單號 out_trade_no 。退款訂單在支付時生成的訂單號
4.退款訂單號 out_refund_no 。由後端生成的退款單號,需要保證唯一,因為多個同樣的退款單號只會退款一次。
5.總金額 total_fee 。訂單總金額,單位為分。
6.退款金額 refund_fee 需要退款的金額,單位同樣為分
7.操作員 op_user_id .與商戶號相同即可
8.隨機字元串 nonce_str 。同支付請求
9.簽名 sign 。使用上面的所有參數進行相應處理加密生成簽名。(具體處理方式與支付相同,可直接復用。)
三. 退款完成
在發起退款請求後,就可以直接根據請求的響應XML中的 result_code欄位來判斷退款是否成功,從而對訂單狀態進行處理和後續操作。不需要像支付那樣等待另一個介面的通知來確定請求狀態。當然如上文所說,如果需要微信伺服器發送通知到後端的話,可以到微信商戶平台進行設置。
退款因為流程與支付大同小異,因此退款的PHP類我選擇了直接繼承支付類,
代碼如下,注意區分退款請求方法postXmlSSLCurl和支付請求方法postXmlCurl的區別,這也就是上文提到的退款需要的雙向證書的使用。
````
class WinXinRefund extends WeiXinPay{
protected \$SSLCERT_PATH = 'cert/apiclient_cert.pem';//證書路徑
protected \$SSLKEY_PATH = 'cert/apiclient_key.pem';//證書路徑
protected \$opUserId = '1234567899';//商戶號
function __construct($openid,$outTradeNo,$totalFee,$outRefundNo,$refundFee){
//初始化退款類需要的變數
$this->openid = $openid;
$this->outTradeNo = $outTradeNo;
$this->totalFee = $totalFee;
$this->outRefundNo = $outRefundNo;
$this->refundFee = $refundFee;
}
public function refund(){
//對外暴露的退款介面
$result = $this->wxrefundapi();
return $result;
}
private function wxrefundapi(){
//通過微信api進行退款流程
$parma = array(
'appid'=> $this->APPID,
'mch_id'=> $this->MCHID,
'nonce_str'=> $this->createNoncestr(),
'out_refund_no'=> $this->outRefundNo,
'out_trade_no'=> $this->outTradeNo,
'total_fee'=> $this->totalFee,
'refund_fee'=> $this->refundFee,
'op_user_id' => $this->opUserId,
);
$parma['sign'] = $this->getSign($parma);
$xmldata = $this->arrayToXml($parma);
$xmlresult = $this->postXmlSSLCurl($xmldata,'https://api.mch.weixin.qq.com/secapi/pay/refund');
$result = $this->xmlToArray($xmlresult);
return $result;
}
//需要使用證書的請求
function postXmlSSLCurl($xml,$url,$second=30)
{
$ch = curl_init();
//超時時間
curl_setopt($ch,CURLOPT_TIMEOUT,$second);
//這里設置代理,如果有的話
//curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
//curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
//設置header
curl_setopt($ch,CURLOPT_HEADER,FALSE);
//要求結果為字元串且輸出到屏幕上
curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE);
//設置證書
//使用證書:cert 與 key 分別屬於兩個.pem文件
//默認格式為PEM,可以注釋
curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLCERT, $this->SSLCERT_PATH);
//默認格式為PEM,可以注釋
curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLKEY, $this->SSLKEY_PATH);
//post提交方式
curl_setopt($ch,CURLOPT_POST, true);
curl_setopt($ch,CURLOPT_POSTFIELDS,$xml);
$data = curl_exec($ch);
//返回結果
if($data){
curl_close($ch);
return $data;
}
else {
$error = curl_errno($ch);
echo "curl出錯,錯誤碼:$error"."<br>";
curl_close($ch);
return false;
}
}}
三. 總結
以上就是關於微信支付和退款的流程及相關知識的介紹。文中的 PHP類 均封裝直接可用。
因為微信支付和退款涉及的東西較為繁雜,很多人直接看官方文檔可能會一頭霧水,所以看過此文了解流程和要點後,再去看微信官方文檔。一方面可以更清晰的了解小程序的支付和退款流程。另一方面,本文因為篇幅有限及作者能力有限,肯定有無暇顧及或有所紕漏之處。為求穩妥,還是需要多看看官方開發文檔。畢竟事涉支付,出個BUG可不是小事。微信小店小程序是微信官方推出的一款免費的商城小程序,但是微信小店小程序不支持實時訂單通知,商家只能在網頁上手動刷新才能知道新的訂單。如何才能實時接收訂單提醒並且在手機上發貨呢?要麼通過第三方服務(成本較大),要麼自己搞定(零成本)。
微信在今年9月份推出了小程序雲開發平台,簡單的說:騰訊為小程序提供免費的伺服器。我們利用騰訊免費的伺服器,就可以實現訂單訂單通知、手機發貨、訂單自動列印等一切功能。
先看視頻吧!這是弄好之後的樣子。可以實時接收訂單通知,自動列印訂單,手機上發貨。仔細看,還有更多功能,更多亮點。如果覺得還行,可以繼續往下看建設步驟。
建設步驟如下:
復用公眾號資質快速創建小程序
申請這個小程序的目的在於獲取騰訊免費伺服器,有了伺服器,什麼都可以搞了。具體申請步驟在這里就不詳細說了,可以自行網路上搜索。
獲取AppId和開發者密碼
要獲取公眾號的AppId和密碼、微信小店AppID,創建的小程序AppId和密碼。這些信息將會導入到創建的小程序中。有了這些信息,小程序才能為微信小店提供服務。
下載微信開發者工具,新建小程序項目
在微信開發者工具中,新建項目。將微信小店小程序關聯到這個小程序裡面來,可以維信搜一搜:采雲。你會看到小程序運行非常快速,碾壓市面上80%的商城小程序。
新建小程序項目
關聯微信小店小程序
訂單提醒
開發建設好之後,商家就可以實時收到微信提醒了。分為2種提醒方式:服務通知和訂單自動列印。服務通知免費,如果是訂單自動列印的話,商家需要購買雲列印機。(就是那種外賣列印機)
服務通知提醒
訂單自動列印提醒
手機上發貨
在收到訂單提醒後,商家可以直接點擊進入小程序發貨界面。並且購買者也能收到發貨提醒。
更多功能(分享朋友圈,會員管理,員工管理等)還沒有寫出來,後期會繼續更新。通過視頻,可以看到更多信息。一定要看哦。
❺ 微信小程序-微信支付簽名驗證
在微信支付之後,小程序會主動向服務端發送支付狀態.為了防止惡意篡改,必須生成簽名發送給服務端進行驗證.
簽名生成官方文檔:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3
簽名驗證分為如下幾步:
1.與服務端確認上傳的簽名內容(即上傳參數key=value)以及加密方式.並且要到商戶平台設置的密鑰key.
2.生成隨機字元串nonceStr.
3.將要上傳的參數,對參數按照key=value的格式,並按照參數名ASCII字典序排序,比如:
假設傳送的參數如下:
appid: wxd930ea5d5a258f4f
mch_id: 10000100
device_info: 1000
body: test
nonce_str: ibuaiVcKdpRxkhJA
則:stringA="appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_id=10000100&nonce_str=ibuaiVcKdpRxkhJA";
4.拼接API密鑰,例如:stringSignTemp=stringA+"&key=" //註:key為商戶平台設置的密鑰key
5.對拼接秘鑰後的字元串進行加密並且轉換為大寫.(加密方式自定)
6.將參數以及加密得到的sign一起上傳給服務端進行驗證.
7.查看服務端返回結果.
謝謝大家~
❻ 微信小程序提示簡訊配置沒有填寫
微信小程序提示簡訊配置填寫的方法詳細內容如下:
第一步:填寫伺服器配置
登錄微信小程序官網後,在小程序官網的「設置-消息伺服器」頁面,管理員掃碼啟用消息服務,填寫伺服器地址(URL)、Token 和 EncodingAESKey。
URL是開發者用來接收微信消息和事件的介面URL。 Token可由開發者可以任意填寫,用作生成簽名(該Token會和介面URL中包含的Token進行比對,從而驗證安全性)。 EncodingAESKey由開發者手動填寫或隨機生成,將用作消息體加解密密鑰,同時,開發者可選擇消息加解密方式:明文模式、兼容模式和安全模式。可以選擇消息數據格式:XML格式或JSON格式。加密方式的默認狀態是明文格式,而數據格式的默認狀態是XML格式,模式的選擇與伺服器配置在提交後都會立即生效,請開發者謹慎填寫及選擇。
第二步:驗證消息來自微信服務端,開發前賣者提交信息後,微信伺服器將發送GET請求到填寫的伺服器地址URL上,GET請求攜帶參數如下表所示:
參數描述
signature微信加密簽名,signature結合了開發者填寫的token參數和請求中的timestamp參數、nonce參數。
timestamp時間戳
nonce隨機數
echostr隨機字元串
開發者通過檢驗signature對請求進行校驗(下面有校驗方式)。若確認此次GET請求來自微信伺服器,請原樣返回echostr參數內容,則接入和高生效,成為開發者成功,否則接入失敗。加密/校驗流程如下: 1、將token、timestamp、nonce三個參數進行字典序排序 2、將三個參數字元串拼接成一個字元串進行sha1加密 3、開發者獲得加密後的字元串可與signature對比,標識該請求來源於微信,要注意的是簽名驗證通過之後,要返回的echostr欄位是字元串喚悔尺,而不是對象。如果返回寫的是 ctx.body = { echostr }就會顯示token驗證失敗。
第三步:依據介面文檔實現業務邏輯,驗證URL有效性成功後即接入生效,成為開發者。至此用戶向小程序客服發送消息、或者進入會話等情況時,開發者填寫的伺服器配置URL將得到微信伺服器推送過來的消息和事件,開發者可以依據自身業務邏輯進行響應。祝您生活愉快,謝謝提問😊
❼ 微信小程序有沒有內測資格有什麼區別
從內測信息來看,小程序在通過向開發者開放多種服務及支撐能力以實現以上設想,主要面向開發者,這些服務和支撐能力包括:
視圖容器:視圖(View)、滾動視圖、Swiper
基礎內容:圖標、文本、進度條
表單組件:按鈕、表單等等
操作反饋
導航
媒體組汪旦件:音頻、圖片、視頻
地圖位置服務
畫布
文件操作能力
網路:上傳下載能力、WebSocket
數據:數據緩存能力
位置:獲取位置、查看位置
設備:敬斗網路狀態、系統信息、重力感應、羅盤
界面:設置導航條、導航、動畫、繪圖等等
開放介面:登錄,包括簽名加密,用戶信息困稿擾、微信支付、模板消息
微信小程序
目前,小程序仍然處於內測階段。全面開放申請後,主體類型為個人、企業、政府、媒體或其他組織的開發者,均可申請注冊小程序。
❽ 微信小程序怎麼弄電子簽名,微信如何電子簽名
1.打開微信」,選擇攜攔沒我」,找到二辯納維碼後的箭頭並點擊。
2.進入個人中衡禪心」,在出現的界面,點擊更多」。
3.點擊個性簽名」,輸入完成,點擊保存」。
❾ 微信小程序如何開發,怎麼獲取openID和用戶信息
1. 獲取openid
1.1 獲取code
首先我們要調用介面來獲取登錄憑證,也就是code,從而獲取用戶們登錄的狀態信息,其中有一個唯一標示,就是openid,還有我們登錄要用到的鑰匙(session_key)。用戶的基本數據我們都要用到鑰匙來獲取數據。
wx.login({
//獲取code
success: function(res) {
code = res.code //返回code
}
})
1.2 獲取openid
拿到上一步獲取派槐的code,結合小程序 appid 和 secret 請求介面api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code 換取openid,與 openid 一同被返回的,還包括 session_key,其中 session_key 是對用戶數據進行加密簽名的密鑰。為塵臘友了自身應用安全,session_key 不應該在網路上傳輸。
wx.request({
url: 'api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code='+ code +'&grant_type=authorization_code',
data: {},
header: {
'content-type': 'application/json'
},
success: function(res) {
openid = res.data.openid //返回openid
}
})
2. 獲取用戶信息
2.1 在app.js中創建該全局方法
//app.js
getUserInfo:function(cb){
var that = this
if(this.globalData.personInfo){
typeof cb == "function" && cb(this.globalData.personInfo)
}else{
//調用登錄介面
wx.login({
success: function () {
wx.getUserInfo({
success: function (res) {
that.globalData.personInfo = res.userInfo
typeof cb == "function" && cb(that.globalData.personInfo)
}
})
}
})
}
}
2.2 實例化全局方法獲取用戶信息
var that = this;
//調用應用實例的方法獲取全局數據
app.getUserInfo(function (personInfo) {
//更新數據局納
that.setData({
personInfo: personInfo
})
})