You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
information-system/webht/third_party/pay/controllers/LianlianService.php

237 lines
13 KiB
PHTML

<?php
defined('BASEPATH') or exit('No direct script access allowed');
class LianlianService extends CI_Controller
{
protected $merchant_config;
protected $private_key;
public function __construct()
{
parent::__construct();
bcscale(2);
$this->load->helper('payment');
$this->config->load('lianlian', true);
$this->load->model('Online_payment_note_model', 'note_model');
$this->load->model('Online_payment_account_model', 'account_model');
$this->merchant_config = $this->config->item('test', 'lianlian');
}
public function index() {}
public function query_status() {}
public function query_payment() {}
public function query_refund() {}
public function notify($site = 'cht')
{
// $this->merchant_config = $this->config->item($site, 'lianlian'); // test: 测试环境
error_reporting(0);
log_message('error', 'LianlianPay notify begin ----');
$response['code'] = 0;
$response['message'] = '';
$raw_post_data = file_get_contents('php://input');
if (empty($raw_post_data)) {
# 如果没有数据,直接返回失败
return $this->output->set_content_type('application/json')->set_output(json_encode($response));
}
log_message('error','test: ' . __METHOD__ . ': ' . __LINE__ . ' ' . PHP_EOL . var_export($raw_post_data, 1));
$signature = $this->input->server('HTTP_SIGNATURE');
$payment_result = json_decode($raw_post_data, true);
if ($this->check_sign($payment_result, $signature) !== true) {
$response['message'] = 'sign error';
// return $this->output->set_content_type('application/json')->set_output(json_encode($response));
}
$payment_data = $payment_result['payment_data'];
$payment_result['GAI_API'] = array(
'merchant' => $site,
'invoice' => $payment_result['merchant_transaction_id'],
'transaction_id' => $payment_result['ll_transaction_id'],
);
// todo: 计算手续费, 实收
$payment_fee = $payment_data['payment_amount'] - $payment_data['settlement_amount'];
$ssje = $this->account_model->get_ssje($payment_data['settlement_amount'], str_replace("CNY", "RMB", strtoupper($payment_data['settlement_currency_code'])), $this->merchant_config['method_code']);
$save_column = array();
$save_column['OPN_transactionId'] = $payment_result['ll_transaction_id'];
$save_column['OPN_orderId'] = $payment_result['merchant_transaction_id'];
$save_column['OPN_rawOrderId'] = $payment_result['merchant_transaction_id'];
$save_column['OPN_invoiceId'] = $payment_result['merchant_transaction_id'];
$save_column['OPN_subject'] = $payment_result['merchant_transaction_id'];
$save_column['OPN_currency'] = $payment_data['payment_currency_code'];
$save_column['OPN_orderAmount'] = $payment_data['payment_amount'];
$save_column['OPN_payAmount'] = $payment_data['payment_amount'];
// $save_column['OPN_payFee'] = $payment_fee; // todo: 计算手续费; 退款 1USD 原手续费不退
$save_column['OPN_netAmount'] = $payment_data['settlement_amount'];
$save_column['OPN_transactionResult'] = $payment_data['payment_status'] === 'PS' ? 'completed' : 'declined';
$save_column['OPN_resultCode'] = $payment_data['payment_status'];
// $save_column['OPN_resultMsg'] = isset($payment_result['return_msg']) ? $payment_result['return_msg'] : $payment_result['result_code'];
// $save_column['OPN_errCode'] = isset($payment_result['err_code']) ? $payment_result['err_code'] : NULL;
// $save_column['OPN_errMsg'] = isset($payment_result['err_code_des']) ? $payment_result['err_code_des'] : NULL;
$save_column['OPN_acquiringTime'] = date('Y-m-d H:i:s', strtotime($payment_data['payment_time']));
$save_column['OPN_completeTime'] = date('Y-m-d H:i:s', strtotime($payment_data['payment_time']));
// $save_column['OPN_remark'] = $payment_result['attach'] ? $payment_result['attach'] : $payment_result['out_trade_no'];
// $save_column['OPN_payerLogId'] = $payment_result['openid'];
// $save_column['OPN_payerStatus'] = $payment_result['is_subscribe']==='Y' ? "subscribed" : NULL;
$save_column['OPN_fundSource'] = $site;
$save_column['OPN_entryAmountCNY'] = floatval($ssje);
$save_column['OPN_rawContent'] = json_encode($payment_result);
$save_column['OPN_noticeTime'] = date('Y-m-d H:i:s');
// $save_column['OPN_noticeType'] = intval($payment_result['total_fee'])>0 ? 'pay' : 'refund';
$save_column['OPN_noticeType'] = 'pay';
$save_column['OPN_noticeSendStatus'] = $payment_data['payment_status'] === 'PS' ? 'unsend' : 'closed';
$save_column['OPN_noticeSendTime'] = NULL;
$save_column['OPN_accountMethod'] = $this->merchant_config['method_code'];
if ($this->note_model->insert_note($save_column)) {
$response['code'] = 200;
$response['message'] = 'success';
}
$this->output->set_content_type('application/json')->set_output(json_encode($response));
}
public function notify_refund($site = 'cht')
{
// $this->merchant_config = $this->config->item($site, 'lianlian'); // test: 测试环境
error_reporting(0);
log_message('error', 'LianlianPay notify refund begin ----');
$response['code'] = 0;
$response['message'] = '';
$raw_post_data = file_get_contents('php://input');
if (empty($raw_post_data)) {
# 如果没有数据,直接返回失败
return $this->output->set_content_type('application/json')->set_output(json_encode($response));
}
$signature = $this->input->server('HTTP_SIGNATURE');
$payment_result = json_decode($raw_post_data, true);
if ($this->check_sign($payment_result, $signature) !== true) {
log_message('error','debug: ' . __METHOD__ . ': ' . __LINE__ . ' signature' . PHP_EOL . var_export($signature, 1));
log_message('error','debug: ' . __METHOD__ . ': ' . __LINE__ . ' raw_post_data' . PHP_EOL . var_export($raw_post_data, 1));
$response['message'] = 'sign error';
// return $this->output->set_content_type('application/json')->set_output(json_encode($response)); // debug:
}
$payment_data = $payment_result['refund_data'];
$find_related = $this->note_model->get_note_where(['OPN_invoiceId' => ['=', $payment_result['original_transaction_id']], 'OPN_transactionResult' => ['=', 'completed']]);
// ! 退款手续费 1USD, 原交易手续费不退
// $payment_fee = $payment_data['payment_amount'] - $payment_data['settlement_amount'];
// $ssje = $this->account_model->get_ssje('-' . $payment_data['actual_refund_amount'], str_replace("CNY", "RMB", strtoupper($payment_data['actual_refund_currency_code'])), $this->merchant_config['method_code']);
$ssje = $this->account_model->get_ssje('-' . $payment_data['settlement_amount'], str_replace("CNY", "RMB", strtoupper($payment_data['settlement_currency_code'])), $this->merchant_config['method_code']);
$save_column = array();
$save_column['OPN_transactionId'] = $payment_result['ll_transaction_id'];
$save_column['OPN_orderId'] = $payment_result['original_transaction_id'];
$save_column['OPN_rawOrderId'] = $payment_result['merchant_transaction_id'];
$save_column['OPN_invoiceId'] = $payment_result['merchant_transaction_id'];
$save_column['OPN_relatedId'] = isset($find_related[0]->OPN_transactionId) ? $find_related[0]->OPN_transactionId : null;
$save_column['OPN_subject'] = $payment_result['merchant_transaction_id'] . ' ' . $payment_data['reason'];
$save_column['OPN_currency'] = $payment_data['refund_currency_code'];
$save_column['OPN_orderAmount'] = '-'.$payment_data['refund_amount'];
$save_column['OPN_payAmount'] = '-'.$payment_data['refund_amount'];
$save_column['OPN_payFee'] = null; // 1; // ! todo: 计算手续费; 退款 1 USD 原手续费不退
$save_column['OPN_netAmount'] = '-'.$payment_data['settlement_amount']; // todo:
$save_column['OPN_transactionResult'] = refund_status($payment_data['refund_status']);
$save_column['OPN_resultCode'] = $payment_data['refund_status'];
// $save_column['OPN_resultMsg'] = isset($payment_result['return_msg']) ? $payment_result['return_msg'] : $payment_result['result_code'];
// $save_column['OPN_errCode'] = isset($payment_result['err_code']) ? $payment_result['err_code'] : NULL;
// $save_column['OPN_errMsg'] = isset($payment_result['err_code_des']) ? $payment_result['err_code_des'] : NULL;
$save_column['OPN_acquiringTime'] = date('Y-m-d H:i:s', strtotime($payment_data['refund_time']));
$save_column['OPN_completeTime'] = date('Y-m-d H:i:s', strtotime($payment_data['refund_time']));
$save_column['OPN_remark'] = $payment_data['reason'] ? $payment_data['reason'] : '';
// $save_column['OPN_payerLogId'] = $payment_result['openid'];
// $save_column['OPN_payerStatus'] = $payment_result['is_subscribe']==='Y' ? "subscribed" : NULL;
$save_column['OPN_fundSource'] = $site;
$save_column['OPN_entryAmountCNY'] = floatval($ssje);
$save_column['OPN_rawContent'] = json_encode($payment_result);
$save_column['OPN_noticeTime'] = date('Y-m-d H:i:s');
$save_column['OPN_noticeType'] = 'refund';
$save_column['OPN_noticeSendStatus'] = refund_status_send($payment_data['refund_status']);
$save_column['OPN_noticeSendTime'] = NULL;
$save_column['OPN_accountMethod'] = $this->merchant_config['method_code'];
// log_message('error','test: ' . __METHOD__ . ': ' . __LINE__ . ' to in' . PHP_EOL . var_export($save_column, 1));
// die; // test:0
if ($this->note_model->insert_note($save_column)) {
$response['code'] = 200;
$response['message'] = 'success';
}
$this->output->set_content_type('application/json')->set_output(json_encode($response));
}
// protected function generateSignArray($params, $signType = "RSA")
// {
// return $this->sign(generateSignContent($params), $signType);
// }
// protected function sign($data, $signType = "RSA")
// {
// $this->private_key = $this->merchant_config['merchant_private_key'];
// $priKey = $this->private_key;
// $res = "-----BEGIN RSA PRIVATE KEY-----\n" .
// wordwrap($priKey, 64, "\n", true) .
// "\n-----END RSA PRIVATE KEY-----";
// ($res) or die('您使用的私钥格式错误请检查RSA私钥配置');
// if ("RSA2" == $signType) {
// openssl_sign($data, $sign, $res, OPENSSL_ALGO_SHA256);
// } else {
// openssl_sign($data, $sign, $res);
// }
// $sign = base64_encode($sign);
// return $sign;
// }
protected function check_sign($data, $signature)
{
if (empty($signature)) {
log_message('error', 'LianlianPay notify error: no sign.');
return false;
}
$verify_res = $this->verify_signature(generateSignContent($data), $signature);
if ( ! $verify_res) {
log_message('error', 'LianlianPay notify error: sign. ' . generateSignContent($data));
return false;
}
// return false; // test: 0
return true;
}
protected function verify_signature($data, $sign, $signType = "RSA")
{
// Load the public key
$pubKey = $this->merchant_config['lianlian_public_key'];
if (!$pubKey) {
return false; // Public key file not found or unreadable.
}
$res = "-----BEGIN PUBLIC KEY-----\n" .
wordwrap($pubKey, 64, "\n", true) .
"\n-----END PUBLIC KEY-----";
$res = openssl_get_publickey($res);
($res) or die('LianlianRSA公钥错误。请检查公钥文件格式是否正确');
//调用openssl内置方法验签返回bool值
if ("RSA2" == $signType) {
$result = (bool)openssl_verify($data, base64_decode($sign), $res, OPENSSL_ALGO_SHA256); // sha256 OPENSSL_ALGO_SHA256
} else {
$result = (bool)openssl_verify($data, base64_decode($sign), $res);
}
// log_message('error', 'test: ' . __METHOD__ . ': ' . __LINE__ . ' result' . PHP_EOL . var_export($result, 1));
//释放资源
openssl_free_key($res);
return $result;
}
}