This project is implemented using Zend Framework frameworks
modules/default/controllers/indexcontroller.php
indexcontroller.php
Copy Code code as follows:
<?php
Class Indexcontroller extends Zend_controller_action
{
Public Function init ()
{
/* Initialize Action Controller Here * *
}
Public Function indexaction ()
{
/* Mock orders
* $MockOrder is the information from the database, which contains some information about the block money request. Here I am writing dead.
*orderid order number, the primary key (unique) of the database table. Required Fields
*usr_idtype certificate type, according to your own needs.
*usr_idcode identification number, according to their own needs.
*etx_status whether preferential, according to their own needs.
*time_create Verify that the time of the concession is met according to your own needs.
*ets_license Package code as a product category, according to your own needs.
*contact_type contact type, fixed selection value 1, 2. 1 Email, 2 cell phone number, according to their own needs, block money over there can be empty.
*contact_text contact, according to Contact_type to fill out, according to their own needs, block money over there can be empty.
*etsprice Package price and commodity price, according to their own needs.
*orderprice actual prices, according to their own needs.
*orderamount the actual payment of the order, which is to be added to the handling fee. Required Fields
*ordertime order time. Required Fields
*paysuccess whether the order was paid successfully. Required Fields
*buysuccess account is successful, according to their own needs
*paytime Order Payment success time. Required Fields
* In general, the order is related to the necessary fields
*orderid, OrderAmount, ordertime required fields for request
*paysuccess, Paytime for response required fields
*/
$MockOrder = Array ();
$MockOrder [' orderId '] = ' 100000125 ';//order number. -Necessary
$MockOrder [' usr_idtype '] = ' 1 ';//certificate type, ID card
$MockOrder [' usr_idcode '] = ' 371111199011111111 ';//ID number
$MockOrder [' etx_status '] = ' 0 ';//whether preferential, no
$MockOrder [' time_create '] = ' 1352338189 ';//verify whether the discount time
$MockOrder [' ets_license '] = ' 1 ';//package Code and product category
$MockOrder [' contact_type '] = ' 1 ';//contact Type 1, mailbox
$MockOrder [' contact_text '] = ' x@163.com ';//contact Way, email
$MockOrder [' etsprice '] = ' 30800 ';//package Price and commodity price
$MockOrder [' orderprice '] = ' 30800 '; actual price
$MockOrder [' orderamount '] = ' 31100 ';//The actual price of the order, plus the handling fee. -Necessary
$MockOrder [' ordertime '] = ' 1352338199 ';//order generation time. -Necessary
$MockOrder [' paysuccess '] = ' 0 ';//whether the order was paid successfully. -Necessary
$MockOrder [' buysuccess '] = ' 0 ';//Account Generation Success
$MockOrder [' paytime '] = ' 0 ';//order payment time. -Necessary
Billrequest is some of the parameters needed for the quick money.
$this->view->billrequest = new Application_model_billrequest ($MockOrder);
Zend_debug::d UMP ($this->view->billrequest); exit;
}
Bgurl address is pointing here.
Public Function receiveaction ()
{
Receive Database design
/* Use $mockreceive array simulation
* $MockReceive = array ();
* $MockReceive [' ID '] primary key;
* $MockReceive [' orderId '] merchant order number;
* $MockReceive [' receivetime '] acceptance time;
* $MockReceive [' QueryString ']http_build_encode ($_request);
* $MockReceive [' dealid '] quick money trading number;
* $MockReceive [' bankdealid '] bank transaction number;
* $MockReceive [' payresult '] processing result 10: Payment success; 11: Payment failure;
* $MockReceive [' dealtime '] quick money trading time;
* $MockReceive [' payamount '] the actual amount of the order paid;
* $MockReceive [' fee '] costs;
* $MockReceive [' errcode '] error code;
*/
/*$_request is the data coming back from the quick money.
* Merchantacctid The RMB account number, which is consistent with the block Money account when submitting the order.
* Version Gateway edition, fixed value: v2.0, consistent with the gateway version number when the order was submitted.
* Language Web page display language categories, 1 Chinese display, and submit the Order of the Web page display language of the same
* Signtype signature Type, 4PKI signature, consistent with type of signature when submitting order
* PayType Payment method, 00 all, consistent with the payment method when submitting the order
* BankID Bank Code
* OrderID Merchant Order number, consistent with the merchant order number when the order is submitted
* Ordertime Merchant Order submission time, consistent with the merchant order submission time when the order was submitted
* OrderAmount The Merchant Order amount in accordance with the merchant Order amount when the order was submitted.
* Dealid Quick Money Trading number
* Bankdealid Bank transaction number
* DealTime Fast Money Trading Time
* Payamount Order Actual payment amount
* Fee Cost
* Ext1 Extended Field 1, consistent with extended field 1 when the order was submitted
* Ext2 Extended Field 2, consistent with extended field 2 when the order was submitted
* Payresult Processing result 10: payment succeeded; 11: Payment failed
* Errcode error code, nullable
* Signmsg Signature String
*/
$BillResponse = new Application_model_billresponse ($_request);
$BillResponse->checksignmsg Verify that the signature string is correct, prevent bug vulnerabilities, etc.
if ($BillResponse->checksignmsg) {
Determine if the order payment is successful
if ($BillResponse->issuccess) {
Return to the quick money, quick money will follow the RedirectURL address to jump to the new page, here is the success page
Return "<result>1</result><redirecturl>http://99bill/default/index/sucess</redirecturl> "; exit;
}else{
Return to the quick money, the quick Money will follow the RedirectURL address to jump to the new page, this is the failure page
return "<result>1</result><redirecturl>http://99bill/default/index/fail</redirecturl>"; Exit
}
}
Return to the quick money, the quick Money will follow the RedirectURL address to jump to the new page, this is the failure page
return "<result>1</result><redirecturl>http://99bill/default/index/fail</redirecturl>"; Exit
}
RedirectURL Address
Success
Public Function Success ()
{
}
Failed
Public function fail ()
{
}
}
Modules/default/views/scripts/index/index.phtml
Https://www.99bill.com/gateway/recvMerchantInfoAction.htm
Copy Code code as follows:
<?php $BillRequest = (array) $this->billrequest;? >
<div style= "Display:none;" >
<form name= "Kqpay" action= "https://www.99bill.com/gateway/recvMerchantInfoAction.htm" method= "POST" >
<?php foreach ($BillRequest as $key => $val):?>
<input type= "hidden" name= "<?php echo $key;? > "value=" <?php echo $val;? > "/>
<?php Endforeach;? >
<input type= "Submit" name= "Submission" value= "submitted to Quick money" id= "Kqpay" >
</form>
</div>
<script>
document.getElementById (' Kqpay '). Click ();
</script>
models/billrequest.php
billrequest.php
Copy Code code as follows:
<?php
Class Application_model_billrequest
{
Public function __construct ($MockOrder) {
/*
* RMB Gateway account number.
* The first way: This account is 11 RMB gateway merchant number +01, this parameter must be filled in. 01 corresponds to ICBC.
* The second way: This account is 16 RMB gateway merchant
*/
$this->merchantacctid = "1001011111101";
The server receives the backend address of the payment result, this parameter must fill in, absolute path//cannot be empty.
$this->bgurl = "http://99bill/default/index/receive";
Merchant Order number, the following time to define the order number, the merchant can be based on their own order number definition rules to define the value//cannot be empty.
$this->orderid = ' tolpc '. sprintf ("%09d", $MockOrder [' orderId ']);
Order amount, the amount in "cent" as the unit, the merchant test can be 1 minutes, do not test with large amount, this parameter must fill///Cannot be empty
$this->orderamount = $MockOrder [' OrderAmount '];
Order submission time, format: YYYYMMDDHHMMSS, such as: 20071117020101//cannot be empty.
$this->ordertime = Date ("Ymdhis", $MockOrder [' ordertime ']);
The name of the payer, which can be empty.
$this->payername= "";
Payer contact type, 1 for email, 2 for phone contact. can be empty.
$this->payercontacttype = "";
The payment person contact method, with Payercontacttype setting corresponds, Payercontacttype is 1, fills in the email address, Payercontacttype is 2, then fills in the mobile phone number. can be empty.
$this->payercontact = "";
The name of the product can be empty.
$this->productname= "TOLPC";
Number of items, can be empty.
$this->productnum = "1";
Commodity code, which can be empty.
$this->productid = $MockOrder [' Ets_license '];
Description of the product, can be empty.
$this->productdesc = "";
The payment method, generally 00, represents all payment methods. If the bank is a direct company merchant, this value is 10, required//cannot be empty
$this->paytype = "00";
Coding method, 1 represents UTF-8; 2 represents GBK; 3 represents GB2312 default of 1, this parameter must fill//cannot be empty
$this->inputcharset = "1";
Gateway version, fixed value: v2.0, this parameter must fill//cannot be empty
$this->version = "v2.0";
Language categories, 1 for Chinese display, 2 for English display. The default is 1, this parameter must fill//cannot be empty
$this->language = "1";
The signature type, which is 4, represents the PKI encryption method, which must be filled///cannot be empty
$this->signtype = "4";
The address of the page that receives the payment result, which is generally null.
$this->pageurl = "";
Extended Field 1, merchants can pass the parameters they need, pay the fast money will return the original value, can be empty.
$this->ext1 = $MockOrder [' orderId '];
Extended from paragraph 2, merchants can pass the parameters they need, pay the fast money will return the original value, can be empty.
$this->ext2 = $MockOrder [' Ordertime '];
Bank code, if the PayType is 00, the value can be null, if PayType is 10, this value must be filled in, please refer to the Bank list.
$this->bankid = "";
The same order to prohibit duplicate submission of the logo, physical shopping cart fill 1, virtual products with 0. 1 representatives can only submit one time, and 0 representatives may resubmit the payment without success. can be empty.
$this->redoflag = "";
Fast Money Partner's account number, that is, the merchant number, can be empty.
$this->pid = "";
Quick Money provides the request parameter.
$KeyOrders = Array (' Inputcharset ', ' pageurl ', ' Bgurl ', ' Version ', ' Language ', ' signtype ', ' merchantacctid ', ' payername ') , ' Payercontacttype ', ' payercontact ',
' OrderId ', ' orderamount ', ' ordertime ', ' productName ', ' productnum ', ' productId ', ' productdesc ', ' ext1 ', ' ext2 ', ' PayType ', ' bankid ', ' redoflag ', ' pid ',);
To determine whether the value of the request parameter provided by the fast money is null, and the non-empty parameters and values are reconstituted into an array
foreach ($KeyOrders as $key) {
if (' = = $this->{$key} ') {continue}
$params [$key] = $this->{$key};
}
Http_build_query () to generate the request string after Url-encode
UrlDecode () restoring an encoded string
GETSIGNMSG () PKI encryption, you can also use MD5 encryption
MD5 encryption Method Strtoupper (MD5 (Http_build_query ($params))); This is not used.
Common PKI Encryption
$this->signmsg = $this->getsignmsg (UrlDecode (Http_build_query ($params)));
}
PKI encryption Technology
Public Function getsignmsg ($param) {
99bill-rsa.pem is a quick-money CA Certificate
Locally randomly generated a key, with this key encryption data key for $PRIV_KEY_ID
$priv _key_id = Openssl_get_privatekey (file_get_contents ("99bill-rsa.pem", "R"));
Use $priv_key_id to encrypt $param data.
Computes a signature string $param encrypted by using SHA1 hash, and then $priv_key_id the private key. The data itself is not encrypted.
Openssl_sign ($param, $SIGNMSG, $priv _key_id, OPENSSL_ALGO_SHA1);
Release $priv_key_id from storage
Openssl_free_key ($priv _key_id);
Using Base64 to encode data
Return Base64_encode ($SIGNMSG);
}
}
models/billresponse.php
billresponse.php
Copy Code code as follows:
<?php
Class Application_model_billresponse
{
/*
* __CONSTRUCT () constructor
* Generate 19 parameters and values, may have a parameter value is NULL, $this->errcode value may be empty
*/
Public function __construct ($response) {
$KeyOrders = Array (' Merchantacctid ', ' Version ', ' Language ', ' signtype ', ' paytype ', ' bankid ', ' orderId ', ' ordertime ', ' OrderAmount ',
' Dealid ', ' bankdealid ', ' dealtime ', ' payamount ', ' fee ', ' ext1 ', ' ext2 ', ' payresult ', ' errcode ', ' signmsg ';
foreach ($KeyOrders as $key) {
$this->{$key} = $response [$key];
}
}
/*
* Check Signature string
* Quick Money The signature string returned is $this->signmsg
* Use base64 to decode the preceding string
* Verify the use of fast money to the public key authentication
* Quick money, they put the returned parameter value is not empty using private key encryption to generate $THIS->SIGNMSG
* Quick Money gives us the private key corresponding to the public key, we use this public key to verify. 1 success, 0 failure,-1 error.
*/
Public Function checksignmsg () {
$KeyOrders = Array (' Merchantacctid ', ' Version ', ' Language ', ' signtype ', ' paytype ', ' bankid ', ' orderId ', ' ordertime ', ' OrderAmount ',
' Dealid ', ' bankdealid ', ' dealtime ', ' payamount ', ' fee ', ' ext1 ', ' ext2 ', ' payresult ', ' Errcode ',);
foreach ($KeyOrders as $key) {
if (' = = $this->{$key} ') {continue}
$params [$key] = $this->{$key};
}
$pub _key_id Public Key
$pub _key_id = Openssl_get_publickey (file_get_contents ("99bill-rsa.cer", "R"));
Return Openssl_verify (UrlDecode (Http_build_query ($params)), Base64_decode ($this->signmsg), $pub _key_id);
}
Public Function issuccess () {
$this->payresult Success 10, failure 11
Return ' ten ' = = $this->payresult;
}
Public Function Getorderid () {
Return Str_replace (' XXX ', ', ', $this->orderid);
}
}
need a public key and a private key, this is not a pair of
It's all half.
99bill-rsa.cer
99bill-rsa.pem