찾다
php教程php手册微信支付之APP支付
微信支付之APP支付Jun 06, 2016 pm 07:37 PM
app플랫폼애플리케이션열려 있는위챗지불하다이동하다통합

微信开放平台移动应用集成微信支付功能。 具体使用请移步:http://www.360us.net/article/23.html 仅仅是消费功能,其他功能没有加。 开放平台的微信支付和公众号的微信支付是不一样的,这里说明一下。 无 ?phpnamespace common\services\WechatPay;class Wec

微信开放平台移动应用集成微信支付功能。
具体使用请移步:http://www.360us.net/article/23.html
仅仅是消费功能,其他功能没有加。

开放平台的微信支付和公众号的微信支付是不一样的,这里说明一下。
<?php
namespace common\services\WechatPay;

class WechatAppPay extends WechatPayBase
{
	//package参数
    public $package = [];
    
    //异步通知参数
    public $notify = [];
    
    //推送预支付订单参数
    protected $config = [];
    
    //存储access token和获取时间的文件
    protected $file;
	
	//access token
	protected $accessToken;
	
	//取access token的url
	const ACCESS_TOKEN_URL = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s';
	
	//生成预支付订单提交地址
	const POST_ORDER_URL = 'https://api.weixin.qq.com/pay/genprepay?access_token=%s';
	
	public function __construct()
	{
		$this->file = __DIR__ . '/payAccessToken.txt';
	}
	
	/**
	 * 创建APP支付最终返回参数
	 * @throws \Exception
	 * @return multitype:string NULL
	 */
	public function createAppPayData()
	{
		$this->generateConfig();
		
		$prepayid = $this->getPrepayid();
		
		try{
			$array = [
				'appid' => $this->appid,
				'appkey' => $this->paySignkey,
				'noncestr' => $this->getRandomStr(),
				'package' => 'Sign=WXPay',
				'partnerid' => $this->partnerId,
				'prepayid' => $prepayid,
				'timestamp' => (string)time(),
			];
			
			$array['sign'] = $this->sha1Sign($array);
			unset($array['appkey']);
		} catch(\Exception $e) {
			throw new \Exception($e->getMessage());
		}
		
		return $array;
	}
	
	/**
	 * 验证支付成功后的通知参数
	 * 
	 * @throws \Exception
	 * @return boolean
	 */
	public function verifyNotify()
	{
		try{
			$staySignStr = $this->notify;
			unset($staySignStr['sign']);
			$sign = $this->signData($staySignStr);
			
			return $this->notify['sign'] === $sign;
		} catch(\Exception $e) {
			throw new \Exception($e->getMessage());
		}
	}
	
	/**
	 * 魔术方法,给添加支付参数进来
	 * 
	 * @param string $name  参数名
	 * @param string $value  参数值
	 */
	public function __set($name, $value)
	{
		$this->$name = $value;
	}
	
	/**
	 * 设置access token
	 * @param string $token
	 * @throws \Exception
	 * @return boolean
	 */
	public function setAccessToken()
	{
		try{
			if(!file_exists($this->file) || !is_file($this->file)) {
				$f = fopen($this->file, 'a');
				fclose($f);
			}
			$content = file_get_contents($this->file);
			if(!empty($content)) {
				$info = json_decode($content, true);
				if( time() - $info['getTime'] < 7150 ) {
					$this->accessToken = $info['accessToken'];
					return true;
				}
			}
			
			//文件内容为空或access token已失效,重新获取
			$this->outputAccessTokenToFile();
		} catch(\Exception $e) {
			throw new \Exception($e->getMessage());
		}
		
		return true;
	}
	
	/**
	 * 写入access token 到文件
	 * @throws \Exception
	 * @return boolean
	 */
	protected function outputAccessTokenToFile()
	{
		try{
			$f = fopen($this->file, 'wb');
			$token = [
				'accessToken' => $this->getAccessToken(),
				'getTime' => time(),
			];
			flock($f, LOCK_EX);
			fwrite($f, json_encode($token));
			flock($f, LOCK_UN);
			fclose($f);
			
			$this->accessToken = $token['accessToken'];
		} catch(\Exception $e) {
			throw new \Exception($e->getMessage());
		}
		
		return true;
	}
	
	/**
	 * 取access token
	 * 
	 * @throws \Exception
	 * @return string
	 */
	protected function getAccessToken()
	{
		$url = sprintf(self::ACCESS_TOKEN_URL, $this->appid, $this->appSecret);
		$result = json_decode( $this->getUrl($url), true );
		
		if(isset($result['errcode'])) {
			throw new \Exception("get access token failed:{$result['errmsg']}");
		}
		
		return $result['access_token'];
	}
	
	/**
	 * 取预支付会话标识
	 * 
	 * @throws \Exception
	 * @return string
	 */
	protected function getPrepayid()
	{
		$data = json_encode($this->config);
		$url = sprintf(self::POST_ORDER_URL, $this->accessToken);
		$result = json_decode( $this->postUrl($url, $data), true );
		
		if( isset($result['errcode']) && $result['errcode'] != 0 ) {
			throw new \Exception($result['errmsg']);
		}
		
		if( !isset($result['prepayid']) ) {
			throw new \Exception('get prepayid failed, url request error.');
		}
		
		return $result['prepayid'];
	}
	
	/**
	 * 组装预支付参数
	 * 
	 * @throws \Exception
	 */
	protected function generateConfig()
	{
		try{
			$this->config = [
					'appid' => $this->appid,
					'traceid' => $this->traceid,
					'noncestr' => $this->getRandomStr(),
					'timestamp' => time(),
					'package' => $this->generatePackage(),
					'sign_method' => $this->sign_method,
			];
			$this->config['app_signature'] = $this->generateSign();
		} catch(\Exception $e) {
			throw new \Exception($e->getMessage());
		}
	}
	
	/**
	 * 生成package字段
	 * 
	 * 生成规则:
	 * 1、生成sign的值signValue
	 * 2、对package参数再次拼接成查询字符串,值需要进行urlencode
	 * 3、将sign=signValue拼接到2生成的字符串后面得到最终的package字符串
	 * 
	 * 第2步urlencode空格需要编码成%20而不是+
	 * 
	 * RFC 1738会把 空格编码成+
	 * RFC 3986会把空格编码成%20
	 * 
	 * @return string
	 */
	protected function generatePackage()
	{
		$this->package['sign'] = $this->signData($this->package);
		
		return http_build_query($this->package, '', '&', PHP_QUERY_RFC3986);
	}
	
	/**
	 * 生成签名
	 * 
	 * @return string
	 */
	protected function generateSign()
	{
		$signArray = [
			'appid' => $this->appid,
			'appkey' => $this->paySignkey,
			'noncestr' => $this->config['noncestr'],
			'package' => $this->config['package'],
			'timestamp' => $this->config['timestamp'],
			'traceid' => $this->traceid,
		];
        return $this->sha1Sign($signArray);
	}
	
	/**
	 * 签名数据
	 * 
	 * 生成规则:
	 * 1、字典排序,拼接成查询字符串格式,不需要urlencode
	 * 2、上一步得到的字符串最后拼接上key=paternerKey
	 * 3、MD5哈希字符串并转换成大写得到sign的值signValue
	 * 
	 * @param array $data 待签名数据
	 * @return string 最终签名结果
	 */
	protected function signData($data)
	{
		ksort($data);
		$str = $this->arrayToString($data);
		$str .= "&key={$this->partnerKey}";
		return strtoupper( $this->signMd5($str) );
	}
	
	/**
	 * sha1签名
	 * 签名规则
	 * 1、字典排序
	 * 2、拼接查询字符串
	 * 3、sha1运算
	 * 
	 * @param array $arr
	 * @return string
	 */
	protected function sha1Sign($arr)
	{
		ksort($arr);
		
		return sha1( $this->arrayToString($arr) );
	}

}
성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
微信文件多久过期微信文件多久过期Nov 21, 2022 pm 02:12 PM

微信文件的过期时间需要根据情况来判断:1、如果发送的文件没有打开过,则在72小时以后微信系统会自动清理掉,即过了三天文件就会过期;2、如果已经查看了微信文件,但是并没有下载(当然已经下载的文件也是一样的),那么文件是可以保留180天的,在这180天以内随时都可以去下载。

微信拉黑和删除有什么区别微信拉黑和删除有什么区别Oct 18, 2022 am 11:29 AM

区别:1、拉黑后对话框从主页消失,但是聊天记录还在;删除后聊天记录全部消失不见了。2、拉黑后还能发给他,但是收不到他的消息;删除后不能发信息了。3、拉黑后双方都不可见彼此的朋友圈;删除对方以后,你看不到对方的朋友圈了,对方是否能看到你的,取决于设置(允许陌生人查看十张照片)与否,如果设置则可以看到朋友圈。

支持微信付款的购物平台有哪些支持微信付款的购物平台有哪些Nov 02, 2022 pm 02:44 PM

支持微信付款的购物平台有:1、京东,是中国的综合网络零售商;2、唯品会,是一家在线销售品牌折扣商品的互联网公司;3、拼多多,是社交新电商领导者,更懂消费者的购物平台;4、京喜,是京东旗下生活消费商城;5、蘑菇街,一个电子商务网站;6、聚美优品,是一家以销售化妆品为主的时尚购物网站;7、微店,是一个云推广电子商务平台;8、考拉海购,是一个跨境海淘业务为主的会员电商平台。

微信怎么查看ip地址微信怎么查看ip地址May 31, 2023 am 09:16 AM

微信查看ip地址的方法:1、登录电脑版微信,右键点击屏幕下方的任务栏,点击“任务管理器”;2、弹出任务管理器时,点击左下角的“详细信息”;3、任务管理器进入“性能”选项,点击“打开资源监视器”;4、选择“网络”,勾选微信进程“Wechat.exe”;5、点击下面的“TCP连接”即可监视微信网络IP相关情况,发送消息得到回复就会显示他人的IP地址。

微信可以绑别人的银行卡号么微信可以绑别人的银行卡号么Mar 14, 2023 pm 04:53 PM

可以。未经过实名认证的微信号,可以绑定他人的银行卡,但在绑定过程中需要提供银行卡的开户人姓名、开户行地址、开户时预留的联系方式及银行卡支付密码;已通过实名认证的微信号,无法绑定他人银行卡,只能添加使用自己身份证办理的银行卡。

一个身份证只能绑定一个微信吗一个身份证只能绑定一个微信吗Mar 02, 2023 pm 01:50 PM

不是,一个身份证能绑定5个微信。按照微信当前规定,一个身份证可以实名认证5个微信号;如果已经实名认证了5个微信账号,但是还想要继续实名,就要把已经实名认证的一些不用的微信号清除以后,才可以再实名认证新的微信号。

闲鱼支持微信支付吗闲鱼支持微信支付吗Nov 07, 2022 pm 03:31 PM

闲鱼是不支持微信支付的,仅支持使用支付宝进行付款;闲鱼是阿里巴巴旗下闲置交易平台App客户端,会员只要使用淘宝或支付宝账户登录,无需经过复杂的开店流程,即可达成包括一键转卖个人淘宝账号中“已买到宝贝”、自主手机拍照上传二手闲置物品、以及在线交易等诸多功能。

微信赞赏码和收款码的区别是什么微信赞赏码和收款码的区别是什么Oct 31, 2022 pm 03:18 PM

区别:1、赞赏码是用于别人给自己打赏的,收取小费等小金额的赞赏给予,而收款码是一般的收款行为,可以进行大额收费的二维码;2、收款码是随时会变的,如果不是商家收款码,每次打开都会变,但是赞赏码不同,赞赏码是不会变的;3、赞赏码只能进行小额的首款,而收款码将可以大额首款。

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

맨티스BT

맨티스BT

Mantis는 제품 결함 추적을 돕기 위해 설계된 배포하기 쉬운 웹 기반 결함 추적 도구입니다. PHP, MySQL 및 웹 서버가 필요합니다. 데모 및 호스팅 서비스를 확인해 보세요.

MinGW - Windows용 미니멀리스트 GNU

MinGW - Windows용 미니멀리스트 GNU

이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)