PHP 백 엔 드 은 련 결제 및 환불 인 스 턴 스 코드

성명:이 글 은 현재 은 련 공식 최신 SDK(2016-08-09 5.1.0 버 전)로 설명 되 어 있 으 며,가방 이 다른 경우 이 버 전 인지 확인 하 십시오.
최근 에 은 련 결제 와 관련 환불(이 글 은 핸드폰 컨트롤 로 만 지불 하 는 것 을 전제 로)작업 을 하 게 되 었 습 니 다.다음은 그 동안 발생 한 문제 와 기본 절 차 를 차례대로 작성 할 것 입 니 다.그 전에 공식 사진 한 장 을 통 해 결제 에서 백 엔 드 직원 에 게 우리 가 해 야 할 일 들 을 알 아 보 겠 습 니 다.

이 를 통 해 알 수 있 듯 이 백 엔 드 는 여기 서 1.플랫폼 주문 생 성 을 책임 집 니 다.2.은 련 전 채널 플랫폼 주문 푸 시;3.tn 코드 를 되 돌려 전단 에 지불 합 니 다.4.프론트 데스크 알림 과 전 채널 플랫폼 의 비동기 알림 을 처리 합 니 다.
이 어 려 운 점 은 세 가지 가 있 습 니 다.주문 푸 시,비동기 통지 처리,주문 상태 조회 입 니 다.
공식 메 일 설명 을 통 해 관련 가방 을 다운로드 하고 백 엔 드 phop 코드 에 넣 습 니 다.그리고 SDK 의 readme.txt 파일 을 자세히 읽 고 다음 절 차 를 진행 합 니 다.
1.관련 매개 변수 설정
도 킹 과정 에서 sdk 의 assets 폴 더 에서 환경 설정 파일 및 인증 서 를 테스트 하고 sdk 폴 더 에 배치 하 며/sdk/SDKConfig.php 파일 이 올 바 르 게 읽 혔 음 을 설정 합 니 다 acpsdk.ini 프로필.
acpsdk.ini 파일 에 acpsdk.signCert.path,acpsdk.encrypter.path,acpsdk.rootCert.path,acpsdk.middleCert.path 네 파일 의 절대 주소(파일 경 로 를 사용자 정의 하면 됩 니 다)를 설정 합 니 다.
프로젝트 개발 과정 에서 시스템 이 다 르 거나 프로젝트 주소 가 다 르 기 때문에 인증서 의 절대 주소 등 오류 가 발생 할 수 있 습 니 다.특히 실제 생산 환경 에서 프로젝트 배치 파일 주소 가 다 르 기 쉬 우 므 로 개발 후 매번 업데이트 할 때마다 인증서 주 소 를 바 꿀 수 없습니다.SDK 의 SDK config.php 는 서로 다른 파일 주 소 를 호 환 했 습 니 다.여 기 는 또 클릭 해서 펼 쳐 보 세 요.

<?php
namespace com\unionpay\acp\sdk;;
include_once 'log.class.php';
include_once 'common.php';
 
class SDKConfig {
   
  private static $_config = null;
  public static function getSDKConfig(){
    if (SDKConfig::$_config == null ) {
      SDKConfig::$_config = new SDKConfig();
    }
    return SDKConfig::$_config;
  }
   
  private $frontTransUrl;
  private $backTransUrl;
  private $singleQueryUrl;
  private $batchTransUrl;
  private $fileTransUrl;
  private $appTransUrl;
  private $cardTransUrl;
  private $jfFrontTransUrl;
  private $jfBackTransUrl;
  private $jfSingleQueryUrl;
  private $jfCardTransUrl;
  private $jfAppTransUrl;
  private $qrcBackTransUrl;
  private $qrcB2cIssBackTransUrl;
  private $qrcB2cMerBackTransUrl;
   
  private $signMethod;
  private $version;
  private $ifValidateCNName;
  private $ifValidateRemoteCert;
   
  private $signCertPath;
  private $signCertPwd;
  private $validateCertDir;
  private $encryptCertPath;
  private $rootCertPath;
  private $middleCertPath;
  private $frontUrl;
  private $backUrl;
  private $secureKey;
  private $logFilePath;
  private $logLevel;
 
  function __construct(){
 
    //    acp_sdk.ini        ,             。
    $configFilePath = dirname(__FILE__) . "/acp_sdk.ini";
    $certsFilePath = dirname(dirname(__FILE__)) . "/certs/";
     
    if(!file_exists($configFilePath)){
      $logger = LogUtil::getLogger();
      $logger->LogError("        ,    :[" . $configFilePath . "].     php         。");
      return;
    }
    $ini_array = parse_ini_file($configFilePath, true);
    $sdk_array = $ini_array["acpsdk"];
    $this->frontTransUrl = array_key_exists("acpsdk.frontTransUrl", $sdk_array)?$sdk_array["acpsdk.frontTransUrl"] : null;
    $this->backTransUrl = array_key_exists("acpsdk.backTransUrl", $sdk_array)?$sdk_array["acpsdk.backTransUrl"] : null;
    $this->singleQueryUrl = array_key_exists("acpsdk.singleQueryUrl", $sdk_array)?$sdk_array["acpsdk.singleQueryUrl"] : null;
    $this->batchTransUrl = array_key_exists("acpsdk.batchTransUrl", $sdk_array)?$sdk_array["acpsdk.batchTransUrl"] : null;
    $this->fileTransUrl = array_key_exists("acpsdk.fileTransUrl", $sdk_array)?$sdk_array["acpsdk.fileTransUrl"] : null;
    $this->appTransUrl = array_key_exists("acpsdk.appTransUrl", $sdk_array)?$sdk_array["acpsdk.appTransUrl"] : null;
    $this->cardTransUrl = array_key_exists("acpsdk.cardTransUrl", $sdk_array)?$sdk_array["acpsdk.cardTransUrl"] : null;
    $this->jfFrontTransUrl = array_key_exists("acpsdk.jfFrontTransUrl", $sdk_array)?$sdk_array["acpsdk.jfFrontTransUrl"] : null;
    $this->jfBackTransUrl = array_key_exists("acpsdk.jfBackTransUrl", $sdk_array)?$sdk_array["acpsdk.jfBackTransUrl"] : null;
    $this->jfSingleQueryUrl = array_key_exists("acpsdk.jfSingleQueryUrl", $sdk_array)?$sdk_array["acpsdk.jfSingleQueryUrl"] : null;
    $this->jfCardTransUrl = array_key_exists("acpsdk.jfCardTransUrl", $sdk_array)?$sdk_array["acpsdk.jfCardTransUrl"] : null;
    $this->jfAppTransUrl = array_key_exists("acpsdk.jfAppTransUrl", $sdk_array)?$sdk_array["acpsdk.jfAppTransUrl"] : null;
    $this->qrcBackTransUrl = array_key_exists("acpsdk.qrcBackTransUrl", $sdk_array)?$sdk_array["acpsdk.qrcBackTransUrl"] : null;
    $this->qrcB2cIssBackTransUrl = array_key_exists("acpsdk.qrcB2cIssBackTransUrl", $sdk_array)?$sdk_array["acpsdk.qrcB2cIssBackTransUrl"] : null;
    $this->qrcB2cMerBackTransUrl = array_key_exists("acpsdk.qrcB2cMerBackTransUrl", $sdk_array)?$sdk_array["acpsdk.qrcB2cMerBackTransUrl"] : null;
 
    $this->signMethod = array_key_exists("acpsdk.signMethod", $sdk_array)?$sdk_array["acpsdk.signMethod"] : null;
    $this->version = array_key_exists("acpsdk.version", $sdk_array)?$sdk_array["acpsdk.version"] : null;
    $this->ifValidateCNName = array_key_exists("acpsdk.ifValidateCNName", $sdk_array)?$sdk_array["acpsdk.ifValidateCNName"] : "true";
    $this->ifValidateRemoteCert = array_key_exists("acpsdk.ifValidateRemoteCert", $sdk_array)?$sdk_array["acpsdk.ifValidateRemoteCert"] : "false";
 
    $this->signCertPath = $certsFilePath . (array_key_exists("acpsdk.signCert.path", $sdk_array)?$sdk_array["acpsdk.signCert.path"]: null);
    $this->signCertPwd = array_key_exists("acpsdk.signCert.pwd", $sdk_array)?$sdk_array["acpsdk.signCert.pwd"]: null;
     
    $this->validateCertDir = array_key_exists("acpsdk.validateCert.dir", $sdk_array)? $sdk_array["acpsdk.validateCert.dir"]: null;
    $this->encryptCertPath = $certsFilePath . (array_key_exists("acpsdk.encryptCert.path", $sdk_array)? $sdk_array["acpsdk.encryptCert.path"]: null);
    $this->rootCertPath = $certsFilePath . (array_key_exists("acpsdk.rootCert.path", $sdk_array)? $sdk_array["acpsdk.rootCert.path"]: null);
    $this->middleCertPath = $certsFilePath . (array_key_exists("acpsdk.middleCert.path", $sdk_array)?$sdk_array["acpsdk.middleCert.path"]: null);
     
    $this->frontUrl = array_key_exists("acpsdk.frontUrl", $sdk_array)?$sdk_array["acpsdk.frontUrl"]: null;
    $this->backUrl = array_key_exists("acpsdk.backUrl", $sdk_array)?$sdk_array["acpsdk.backUrl"]: null;
     
    $this->secureKey = array_key_exists("acpsdk.secureKey", $sdk_array)?$sdk_array["acpsdk.secureKey"]: null;
    $this->logFilePath = array_key_exists("acpsdk.log.file.path", $sdk_array)?$sdk_array["acpsdk.log.file.path"]: null;
    $this->logLevel = array_key_exists("acpsdk.log.level", $sdk_array)?$sdk_array["acpsdk.log.level"]: null;
     
  }
 
  public function __get($property_name)
  {
    if(isset($this->$property_name))
    {
      return($this->$property_name);
    }
    else
    {
      return(NULL);
    }
  }
 
}
2.전 채널 상품 주문 푸 시
관련 코드

use com\unionpay\acp\sdk\AcpService;
use com\unionpay\acp\sdk\LogUtil;
use com\unionpay\acp\sdk\SDKConfig;
 
  /**
   *       
   *
   * @param $orders
   * @param $orders_type
   * @return array
   */
  public function unionPay($orders, $orders_type = 0)
  {
    include_once dirname(dirname(dirname(__FILE__))) . '/Model/unionpay-sdk/sdk/acp_service.php';
    $config = new SDKConfig();
    $AcpService = new AcpService();
    $log = LogUtil::getLogger();
    $time = date('YmdHis', time());
    $params = array(
 
      //              
      'version' => $config->getSDKConfig()->version,         //   
      'encoding' => 'utf-8',         //    
      'txnType' => '01',           //    
      'txnSubType' => '01',         //    
      'bizType' => '000201',         //    
      'frontUrl' => $config->getSDKConfig()->frontUrl, //      
      'backUrl' => $this->getURL('api_pay_unionpay_call_back'),  //      
      'signMethod' => $config->getSDKConfig()->signMethod,         //    
      'channelType' => '08',         //    ,07-PC,08-  
      'accessType' => '0',        //    
      'currencyCode' => '156',      //    ,      156
 
      //TODO         
      'merId' => $this->getParameter('mer_id'),   //    ,          
      'orderId' => $orders["order_no"],  //     ,8-32     ,   “-” “_”
      'txnTime' => $time, //      ,   YYYYMMDDhhmmss,     
      'txnAmt' => $orders['total_price'] * 100,  //    ,   
    );
 
    $AcpService->sign ( $params ); //   
    $url = $config->getSDKConfig()->appTransUrl;
 
    $result_arr = $AcpService->post ($params, $url);
 
    if(count($result_arr)<=0) { //   200      $log->LogInfo('   200     ');
    }
 
//    $this->printResult ($url, $params, $result_arr ); //          
 
    if (!$AcpService->validate ($result_arr) ){
      $log->LogInfo('        ');
    }
    if ($result_arr["respCode"] == "00"){
      //  
      return array('txn_time'=>$time, 'tn'=>$result_arr["tn"]);
//      echo "     tn      ,     tn         。

"; // echo " demo tn, tn, ,【 tn】。
"; } else { // return array('txn_time'=>$time, 'tn'=>0); //echo " :" . $result_arr["respMsg"] . "。
"; } }
txnTime 형식 이 잘못 전송 되 지 않도록 주의 하 십시오.테스트 환경 에서 문제 가 없 을 것 입 니 다.받 은 tn 을 앱 으로 되 돌려 지불 하면 됩 니 다.
3.비동기 알림 처리 및 주문 거래 상태 조회
이 단 계 는 은 련 거래 의 성공 정 보 를 처리 하고 가능 한 한 리 셋 미 처리 로 인 한 문 제 를 피 하 는 데 주요 역할 을 한다.
먼저 비동기 통지 처 리 를 말 하고 이 절 차 는 주문 상태 수정 의 주요 근거 이다.실제 난점 이 없 으 면 관련 매개 변수 에 문제 가 없 음 을 보증 하면 된다.

/**
   *     
   *
   * @param Request $request
   * @return array|Response
   */
  public function unionPayCallBackAction(Request $request)
  {
    if ($request->get('type') == 1){//    -        
      $query = $this->unionPayQuery($request, array(), 1);
 
      return new JsonResponse($query);
    }
 
    require_once dirname(dirname(dirname(__FILE__))) . "/Model/unionpay-sdk/sdk/acp_service.php";
    $log = LogUtil::getLogger();
    $AcpService = new AcpService();
 
 
    if ($request->request->has('signature') && $AcpService->validate($_POST)) {
      $order_no = $request->request->get('orderId');
      $respCode = $request->request->get('respCode');
      $total = $request->request->get('txnAmt'); //     
      if ($respCode === '00' || $respCode === 'A6') {
        $trade_no = $request->request->get('origQryId')?:'UN' . date('YmdHis', time()) . substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
        $this->dispose($order_no, $trade_no, 4);//      -           
      }
    } else {
      if (!$request->request->has('signature')) {
        $log->LogInfo('    ');
      } else {
        $log->LogInfo('    ');
      }
    }
 
    exit;
  }
주문 거래 상태 조회

   do{//    ,          queryID
      sleep($number * 2);
      $query = $this->unionPayQuery('', $orders);
      $number += 1;
    }while($query['errorCode'] != 0 || empty($query['result_arr']["queryId"]));
 
public function unionPayQuery($request, $orders)
  {
    require_once dirname(dirname(dirname(__FILE__))) . "/Model/unionpay-sdk/sdk/acp_service.php";
    $config = new SDKConfig();
    $AcpService = new AcpService();
    $log = LogUtil::getLogger();
    $params = array(
      //              
      'version' => $config->getSDKConfig()->version,    //   
      'encoding' => 'utf-8',     //    
      'signMethod' => $config->getSDKConfig()->signMethod,     //    
      'txnType' => '00',       //    
      'txnSubType' => '00',     //    
      'bizType' => '000000',     //    
      'accessType' => '0',    //    
      'channelType' => '07',     //    
 
      //TODO         
      'orderId' => $orders['order_no'],  //             ,8-32     ,   “-” “_”
      'merId' => $this->getParameter('mer_id'),   //    ,          
      'txnTime' => date('YmdHis', time()), //                ,   YYYYMMDDhhmmss
    );
 
    $AcpService->sign ( $params ); //   
    $url = $config->getSDKConfig()->singleQueryUrl;
 
    $result_arr = $AcpService->post ( $params, $url);
    if(count($result_arr)<=0) { //   200      $log->LogInfo('   200     ');
    }
 
    if (!$AcpService->validate ($result_arr) ){
      $log->LogInfo('        ');
    }
    if ($result_arr["respCode"] == "00"){
      if ($result_arr["origRespCode"] == "00"){
        //    
        $trade_no = 'UN' . date('YmdHis', time()) . substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
        $this->dispose($orders['order_no'], $trade_no, 4);
        $result = array('errorCode'=>0, 'message'=>'    ', 'result_arr'=>$result_arr);
 
      } else if ($result_arr["origRespCode"] == "03"
        || $result_arr["origRespCode"] == "04"
        || $result_arr["origRespCode"] == "05"){
        //                   
 
        $result = array('errorCode'=>2, 'message'=>'     ', 'result_arr'=>$result_arr);
 
      } else {
        //           
 
        echo "    :" . $result_arr["origRespMsg"] . "。

"; $result = array('errorCode'=>1, 'message'=>" :" . $result_arr["origRespMsg"] . ".", 'result_arr'=>$result_arr); } } else if ($result_arr["respCode"] == "03" || $result_arr["respCode"] == "04" || $result_arr["respCode"] == "05" ){ // $result = array('errorCode'=>2, 'message'=>" , .", 'result_arr'=>$result_arr); } else { // $result = array('errorCode'=>1, 'message'=>" :" . $result_arr["respMsg"] . ".", 'result_arr'=>$result_arr); } return $result; }
여기까지 만 주문 라인 환불 이 없 으 면 완 료 됩 니 다.
주문 환불 관련

public function refundUnionPay($orders)
  {
    require_once(dirname(dirname(__FILE__)) . "/Model/unionpay-sdk/sdk/acp_service.php");
 
    set_time_limit(100);
 
    $config = new SDKConfig();
    $AcpService = new AcpService();
    $log = LogUtil::getLogger();
    $number = 0;
    do{//    ,          queryID
      sleep($number * 2);
      $query = $this->unionPayQuery('', $orders);
      $number += 1;
    }while($query['errorCode'] != 0 || empty($query['result_arr']["queryId"]));
   
 
    if ($query['errorCode'] != 0) {
      return array('errorCode'=>1, 'message'=>'     ,    ');
    }
    $params = array(
 
      //              
      'version' => $config->getSDKConfig()->version,      //   
      'encoding' => 'utf-8',       //    
      'signMethod' => $config->getSDKConfig()->signMethod,       //    
      'txnType' => '04',         //    
      'txnSubType' => '00',       //    
      'bizType' => '000201',       //    
      'accessType' => '0',      //    
      'channelType' => '07',       //    
      'backUrl' => $config->getSDKConfig()->backUrl, //      
 
      //TODO         
      'orderId' => "T" . $orders['order_no'],   //     ,8-32     ,   “-” “_”,        ,    -            T
      'merId' => $this->getParameter('mer_id'),     //    ,         
      'origQryId' => $query['result_arr']["queryId"], //    queryId,                
      'txnTime' => date('YmdHis', time()),    //      ,   YYYYMMDDhhmmss,    ,      
      'txnAmt' => $orders['total_price'] * 100,   //    ,              
    );
 
    $AcpService->sign ( $params ); //   
    $url = $config->getSDKConfig()->backTransUrl;
 
    $result_arr = $AcpService->post ( $params, $url);
    if(count($result_arr)<=0) { //   200      return array('errorCode'=>1, 'message'=>"     .");
    }
 
    if (!$AcpService->validate ($result_arr) ){
      return array('errorCode'=>1, 'message'=>"        .");
    }
 
    if ($result_arr["respCode"] == "00"){
      //     ,              ,                    
      return array('errorCode'=>0, 'message'=>"    .");
 
    } else if ($result_arr["respCode"] == "03"
      || $result_arr["respCode"] == "04"
      || $result_arr["respCode"] == "05" ){
      //                   
      return array('errorCode'=>1, 'message'=>"    ,     .");
    } else {
      //           
 
      return array('errorCode'=>1, 'message'=>"  :" . $result_arr["respMsg"] . ".");
    }
  }
반환 상태 값 에 따라 관련 조작 을 하면 됩 니 다.실제 논리 코드 는 스스로 실현 하 십시오.
생산 환경 을 전환 하 다.
프로젝트 관계 진행 불가-추가 보충
미 완성 계속...
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기