Red de conocimiento informático - Problemas con los teléfonos móviles - Pago del subprograma WeChat Thinkphp5.1

Pago del subprograma WeChat Thinkphp5.1

Después de investigar durante varios días, también encontré dificultades. Busqué en Baidu durante mucho tiempo y ahora finalmente lo descubrí y lo compartí.

También eché un vistazo a esto y fue escrito por alguien. demás.

función pública unifiedorder($order_no, $openid, $total_fee, $attach, $order_id, $user_id){

// Hora actual

$time = time();

// Generar cadena aleatoria

$nonceStr = md5($time .$openid);

// Parámetros API

$params = [

'appid' => $this->appid, ? // Mini ID de programa asignado por WeChat

'attach' => $attach, ? // Los datos adjuntos devueltos en la API de consulta y las notificaciones de pago se pueden utilizar como parámetros personalizados.

'body' => 'membership', ? // Descripción de la actividad de recaudación de fondos

'mch_id' => $this->mchid, // Número de comerciante asignado por WeChat Pay

'nonce_str' => $nonceStr, ? // Cadena aleatoria, hasta 32 caracteres

'notify_url' => $this->notify_url, // base_url() . aviso .php?s=/task/notify/order/wxapp_id/'. $wxapp_id, // Dirección de notificación asincrónica

'openid' => $openid, ? //ID de usuario; trade_type=JSAPI, se debe pasar este parámetro, que es el ID único del usuario bajo el appid del comerciante.

'out_trade_no' => $order_no, ? // Número de factura del comerciante

'spbill_create_ip' => \request()->ip(), // IP de terminal compatible con IPV4; y dirección IP en formato IPV6. IP de la máquina que llama a la API de pago de WeChat

'total_fee' => (int)$total_fee * 100, // precio:centavos unitarios ?// Precio: centavos unitarios

'trade_type ' = > 'JSAPI', ? // trade_type

];

// Generar firma

$params['sign'] = $this-> makeSign( $params);? // Este es el lugar más lamentable, solo es necesario configurar 1.

El appid y el número de comerciante deben estar vinculados

// Solicitar API

$url = '/pay/unifiedorder';

$result = $this- > post($url, $this->toXml ($params));

$prepago = $this->fromXml($resultado);

//agregar prepay_id

$data = [

'user_id' =>$user_id,

'order_id' => $order_id,

p>

'attach' => json_encode($attach),

'prepay_id' => $prepay['prepay_id'],

];

(new AppleWxPrepay())->addInfo($data);

// Solicitud fallida

if ($prepay['return_code'] === 'FAIL' ) {

return [API_CODE_NAME =>.2000004, API_MSG_NAME => $prepago['return_msg']];

}

if ($prepago[' result_code '] === 'FAIL') {

return [API_CODE_NAME => ; 2000004, API_MSG_NAME => $prepago['err_code_des']];

// Genera nonce_str para uso front-end

$paySign = $this->makePaySign($params[ 'nonce_str'], $prepay['prepay_id'], $time);

return [

'prepay_id' => $prepay['prepay_id'],

'nonceStr' =>$nonceStr ,

'timeStamp ' => (cadena)$hora,

'paySign' => $paySign

]; **

* Generar firma

* @param $values

* @return string Esta función no sobrescribe la variable miembro de signo si desea establecerla. la firma, debe llamar al método SetSign Assignment

*/

función privada makeSign($values)

{

/ /Paso 1 de la firma: ordenar los parámetros en el orden del diccionario

ksort($values);

$string = $this->toUrlParams($values);

//Firma Paso 2: Agregar CLAVE después de la cadena

$string = $string .'&key=' .$this->apikey;

/ /Firma paso 3: cifrado MD5

$string = md5($string);

//Firma paso 4:

Convierte todos los caracteres a letras mayúsculas

$resultado = strtoupper($string);

Devuelve $resultado;

}

/ * *

* Formatear parámetros en parámetros de URL

* @param $values

* @return string

*/

función privada toUrlParams($valores)

{

$buff = '';

foreach ($valores como $k => $ v) {

if ($k != 'sign' && $v ! = '' && !is_array($v)){

$buff .'=' . v .'&';

}

}

Retorno de retorno($buff, '&');

}< / p>

/**

* Simular solicitud POST

* @param $url

* @param array $data

* @param bool $useCert

* @param array $sslCert

* @return mixto

*/

publicación de función pública ($url, $data = [], $ useCert = false, $sslCert = [])

{

$header = [

'Contenido - escriba:

$curl = curl_ init();

curl_setopt($curl, CURLOPT_URL, $url

curl_setopt($curl, CURLOPT_HTTPHEADER, $); encabezado);

curl_setopt($curl, CURLOPT_HEADER, false);

curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

curl_setopt($curl, CURLOPT_SSL_VERIFYPEER , falso);

curl_setopt($curl, CURLOPT_POST, TRUE);

curl_setopt($curl, CURLOPT_POSTFIELDS, $datos);

if ($ useCert == true) {

//Establecer el certificado: el certificado y la clave pertenecen a dos archivos .pem independientes.

archivo 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']);

}

$resultado = curl_exec($curl);

curl_close($curl);

devuelve $resultado;

}

/ **

* Caracteres xml de salida

* @param $ valores

* @return bool|string

*/

función privada toXml($valores)

{

if (!is_array($valores) || count($valores) & lt;= 0) {

devuelve falso;

}

$xml = "";

foreach ($valores como $clave => $val ) {

if (is_numeric($val)) {

$xml ="<".$key .">" .$val ."";

} else {

$xml .$clave ."> ";

}

}

$xml .= "";

Devolver $ xml;

}

/**

* Convertir xml a matriz

* @param $xml

* @return mixto

*/

función privada fromXml($xml)

{

// Deshabilitar el acceso a xml externo entidades Cita

libxml_disable_entity_loader(true);

Devuelve json_decode(json_ encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);

}

/**

* Generar paySign

* @param $ nonceStr

* @param $ prepay_id

* @param $timeStamp

* @return string

*/

función privada makePaySign($nonceStr, $prepay_id , $timeStamp)

{

$datos = [

'aplicaciónI

d' =>$this->appid,

'nonceStr' => $nonceStr,

'package' =&> 'prepay_id=' .$prepay_id,

'signType' => 'MD5',

'timeStamp' => $timeStamp,

];

// Paso 1 de firma: Ordenar los parámetros en orden lexicográfico

ksort($data);

$string = $this->toUrlParams($data);

// Firma Paso 2: En cadena Luego add KEY

$string = $string .'&key=' .$this->apikey;

// Firma paso 3: cifrado MD5

$ string = md5($string);

// Firma paso 4: convertir todos los caracteres a letras mayúsculas

$resultado = strtoupper($string);

return $resultado;

}

/****************************** * *** devolución de llamada de Microsoft************************

función pública getNotify()

{

p>

if (!$xml = file_get_contents('php://input')){

$this->returnCode(50000001, 'DATOS no encontrados');

}

// Convierte los datos XML devueltos por el servidor en una matriz

$data = $this->fromXml($xml);

$ payLog = new ApplePayLog();

// Registro de registro

$payLog->addInfo(['content'=>json_ encode($xml)]) ;

$payLog->addInfo(['content'=>json_encode($data)]);

// Crear una instancia del modelo de facturación

$OrderModel = new AppleOrder();

// Información de facturación

$orderInfo = $OrderModel->getInfo(['id' =>$data[ 'attach']],'*');

if (empty($orderInfo)) {

$this-& gt;returnCode(50000001, ' La factura no existe' );

}

if ($orderInfo['pay_status'] ! = 1 || !empty($orderInfo['pay_time'])){

$this->returnCode(50000001,'El pedido ha sido pagado, por favor no vuelva a pagar');p>

> }

}

// Guarda la firma devuelta por el servidor WeChat

$ dataSign = $data['sign'];

$return_code = $data['return_code'];

$result_code = $data['result_code'];

$data['body'] = 'Tarjeta de miembro' ;

$datos['spbill_create_ip'] = \request()->ip();

$datos['notify_url'] = $this->notify_url;

// Los parámetros sign y s no participan en el algoritmo de firma

unset($data['sign']);

unset($data['transaction_id ']);

p>

unset($data['coupon_id']);

unset($data['coupon_type']);

unset ($datos['coupon_count'] );

unset($data['coupon_fee']);

unset($data['time_end']);

unset($datos[ 'return_ code']);

unset($datos['result_code']

Unset($datos['is_subscribe'])

Cancelar configuración ($data['fee_type']);

Cancelar configuración ($data['bank_type']);

Cancelar configuración ($; data['bank_type']) ;

// Generar firma

$sign = $this->makeSign($data);

// Confirmar firma ¿Es correcto? Determinar el estado del pago

if (($sign === $dataSign) && ($return_code == 'SUCCESS') && ($result_code == 'SUCCESS')){

$OrderModel->.startTrans();

intente {

// El pago de la factura se procesó correctamente

$appleOrderInfo = $OrderModel->where([' id'=>$orderInfo['id']])-> lock(true )->find();

$resultado = $appleOrderInfoo->addInfo(['pay_status'=>2, 'pay_time'=>time()],['id'=>$orderInfo['id']);

if(!$resultado){

$OrderModel-> rollback();

$this->returnCode(5000003, 'Error al modificar el pedido, motivo del error: '.$OrderModel->getError());

}

$appleUserModel = nuevo AppleUser();

> $appleUserInfo = ?$appleUserModel->where(['openid'=>$orderInfo['openid']])->lock(true)->find();

$appleUser = $appleUserInfo ->where(['openid'=>$orderInfo['openid']])->setInc('moxibustión',$orderInfo['moxibustión']);

if(!$appleUser) {

$OrderModel->rollback();

$this->returnCode(5000003,'Error al agregar los tiempos de acupuntura de los miembros, motivo del error:'.$appleUserModel->getError( ) );

}

}catch (\Exception $excepción){

$OrderModel->rollback();

$ this ->. returnCode(5000003, 'Operación fallida, motivo del error: '.$exception->getMessage());

}

$OrderModel->commit();

// Estado de devolución

die(json(['code'=>0,'Pago exitoso']));

}

// Estado de devolución

// Estado de devolución.

// Estado de devolución

$this->returnCode(2000003, 'Falló la firma');

}