Norvik BankLink izveides paraugs

Sveiki, kā jau solīju kādu laiku atpakaļ, šeit ir paša rakstīts Norvik BankLink izveides īss manuālis.

Es personīgi esmu izveidojis divus dažādus failus, vienu requestam ( request.php ), otru responsei ( response.php ).

request.php

Pašam bankas requestam ir jābūt post formātā ar 3 laukiem: LANG, DATA un MAC

Manā gadījumā tas izskatās šādi:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <title>Banklink</title>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
  <form method="post" name="bank_form" id="bank_form" action=" ' . self::getBankServer() . '" accept-charset="UTF-8">
    <input type="hidden" name="LANG" value="' .  self::getPrefLang() . '" />
    <input type="hidden" name="DATA" value="' . self::getXMLData() . \" />
    <input type="hidden" name="MAC" value="' . self::getMac() . '" />
  </form>
  <script type="text/javascript" language="javascript">
    document.bank_form.submit();
  </script>
</body>
</html>


LANG:

LV, RU vai EN ( domājams ka komentārus neprasa )

DATA:

Sastāv no XML veida pieprasījuma šādā izskatā:

<?xml version="1.0" encoding="UTF-8" ?>
<bl>
    <snd>' . self::getSender() . '</snd>
    <query>NEW</query>
    <type>' . self::getSenderType() . '</type>
    <data>
        <CLIENT_ID>' . self::getVendorId() . '</CLIENT_ID>
        <AMOUNT>' . self::getOrderAmount() . '</AMOUNT>
        <CCY_NAME>LVL</CCY_NAME>
        <CCY_CODE>1</CCY_CODE>
        <BNF_NAME>' . self::getCompanyName() . '</BNF_NAME>
        <BNF_ACCOUNT>' . self::GetVendorAccount() . '</BNF_ACCOUNT>
        <BNF_ID>' . self::getVendorRegCode() . '</BNF_ID>
        <RESIDENCE_ID>LV</RESIDENCE_ID>
        <RESIDENCE_NAME>LV-LATVIA</RESIDENCE_NAME>
        <DETAILS>' . self::getPaymentDetails() .'</DETAILS>
    </data>
    <date>' . date( "dmY" ) . '</date>
    <time>' . date( "His" ) . '</time>
    <reply>
        <session_id>' . self::getSessionId() . '</session_id>
    </reply>
    <reply_url>' . self::getReturnUrl() . '</reply_url>
</bl>


Note: Laukiem ir obligāti jānūt ar LIELAJIEM un mazajiem burtiem!

Apskatam katru lauku un tā izveidi:

snd = Sūtītāja vārds
query = NEW
type = Sūtītāja tips ( norāda banka )
date = Aktuālais datums formātā "dmY"
time = Aktuālais laiks formātā "His"
reply_url = Adrese, uz kuru banka nosūtīs responsi

replay:
session_id = Unikāls sessijas ID bankas vajadzībām

data:
CLIENT_ID = Bankas piešķirtais uzņēmuma ID
AMOUNT = Summa
CCY_NAME = Valūta LVL vai EUR
CCY_CODE = Valsrts kods ( 1 = Latvija )
BNF_NAME = Uzņēmuma pilns nosaukums
BNF_ACCOUNT = Uzņēmuma Norvik bankas konts
BNF_ID = Uzņēmuma reģistra kods
RESIDENCE_ID = Uzņēmuma rezidence ( LV = Latvija )
RESIDENCE_NAME = Rezidences pilns nosaukums = LV-LATVIA
DETAILS = Maksājuma mēķis

MAC:

Šī ir svarīgākā daļa. Lai banka pieņemtu maksājumu, ir nepieciešams izveidot MAC, kas sastāv no XML hash vērtības, kas ir parakstīta ar uzņēmuma privāto atslēgu un pēc tam pārvērsta base64 kodējumā.

Nolasam privāto atslēgu:

private function setPrivateKey( $key_name ) {
    $fp = fopen( self::getKeyLocation() . '/' . $key_name, "r" );
    $priv_key = fread( $fp, 8192 );
    fclose( $fp );

    $this -> private_key = openssl_get_privatekey( $priv_key );
}


Izveidojam parakstu:
private function setSignature() {
    openssl_sign( self::getXMLData(), $signature, self::getPrivateKey() );
    $this -> signature = $signature;
}

Nokodējam un izveidojam MAC vērtību:
private function setMac() {
    $this -> mac = base64_encode( self::getSignature() );
}

Tad kad visas šīs vērtības ir gatavas, saliekam tās jau pieminētajā HTML formā un izpildam to. Voila!

response.php

Ar responsi ir stipri vienkāršāk. Banka atbildi sūta principā tādā pašā paskatā, kā mēs savu pieprasījumu: LANG, DATA, MAC

DATA

Šeit mums ir pamata vērtības ( principā viss kas mums ir vajadzīgs ):

<?xml version="1.0" encoding="UTF-8" ?>
<bl>
    <snd>NORVIKBANK</snd>
    <rcv>Company Name</rcv>
    <date>28042008</date>
    <time>110536</time>
    <reply>
        <session_id>Muusu nosuutiitais session ID</session_id>
    </reply>
    <status>12</status>
</bl>


Principā, kas mums šeit ir vajadzīgs ir [b]status[/b], kas norāda, kas ar mūs interesējušo maksājumu ir noticis.
10    =    Signed
11    =    Processing
12    =    Accepted Payment
20    =    Rejected Payment


MAC

Laigan DATA mums jau ir mūs interesējošā informācija, šis lauks ir OBLIGĀTI jāpārbauda. Pretējā gadījumā jebkurš, kas zina tavu response url, var iesūtīt veiksmīgu maksājumu, ko protams tu īsti nevēlētos.

Tātad, nolasam mak atsūtīto signaturi, kas ir izveidota tādā pašā veidā, kā mūsu jau sūtītā:

private function checkSignature( $key_name ) {
        
    $signature = base64_decode( $this -> getMac () );
        
    $fp = fopen( self::getKeyLocation() . '/' . $key_name, "r" );
    $cert = fread( $fp, 8192 );
    fclose( $fp );
    $pubkeyid = openssl_get_publickey( $cert );
        
    $ok = openssl_verify( self::getData(), $signature, $pubkeyid );
    if ( $ok == 1 ) {
           $return = true;
    } else {
           $return = false;
    }
        
    openssl_free_key( $pubkeyid );

    return $return;

}


Kad tas ir pārbaudīts, vienkārši apskatam mūsu responses status un izveidojam attiecīgu atbildi!

private function getResponseStatus() {
    
    $xml = simplexml_load_string( self::getData() );
    $status = (array)$xml -> status;
    $session_id = (array)$xml -> reply -> session_id;
    $this -> setSessionId( $session_id[ 0 ] );
    return $status[ 0 ];

}
    
switch ( self::getResponseStatus() ) {
            
    # Signed
    case "10":
        // Signed
    break;
        
    # auto bank response about payment process
    case "11":
        // Processed
    break;
            
    # auto bank response about finished payment
    case "12":
        // Finished
    break;
            
    # Rejected Payment
    case "20":
        // Failed
    break;
}


Tas arī viss!
http://www.bitcoinplus.com/generate?for=33936382