2016-01-25 1 views
0

У меня есть настольное приложение Foxpro 9.0 Executive, которому необходимо подключиться к Payeezy и передавать и получать XML-данные через их API. Я использовал WinHttpRequest.5.1 для отправки и получения XML-данных из API проверки адреса UPS. Но у меня, похоже, проблема с заголовком расчета хеша SHA-1 HMAC. Может ли кто-нибудь дать мне небольшой пример кода о том, как это сделать в Foxpro? https://support.payeezy.com/hc/en-us/articles/203731149-API-Security-HMAC-HashFoxPro Payeezy Gateway

*api.demo.globalgatewaye4.firstdata.com 
*************************** 
If Vartype(loReq)='U' 
    Public loReq 
ENDIF 
lcURL='https://api-cert.payeezy.com/v1/transactions/v12' 
lcPassWd ='Password' 
lcExactID='ExactID' 
lcKeyCode='Keycode' 
ldDate=dtos(DATE()) 
lcDate=SUBSTR(ldDate,1,4)+'-'+SUBSTR(ldDate,5,2)+'-'+SUBSTR(ldDate,7,2) 
ltTime=TIME() 
lcDateTime=lcDate+'T'+TRANSFORM(ltTime)+'Z' 
uri='transaction/v12' 
lcTranstype='00' 
lcAmount='1299.00' 
lctype='visa' 
lcname='John Smith' 
lncc_no='4788250000028291' 
lcExp_Date='1020' 
lccvv='123' 
lcAddress='21 Jump Street' 
lcCity='Los Angeles' 
lcZip='90210' 
lcPhone='5557891234' 
lcOrderno='12345678' 
CustID='87654321' 
lcTransactionType="00" 
lcShip_Name="Customer Name" 
XMLRequest='<?xml version="1.0" encoding="utf-8" ?>'+Chr(13)+; 
    '<Transaction>'+Chr(13)+; 
    '<Transaction_Type>'+lcTranstype+'</Transaction_Type>'+CHR(13)+; 
    '<DollarAmount>'+lcAmount+'</DollarAmount>'+CHR(13)+; 
    '<Expiry_Date>'+lcExp_Date+'</Expiry_Date>'+CHR(13)+; 
    '<CardHolderName>'+lcname+'</CardHolderName>'+Chr(13)+; 
    '<Reference_No>'+lcOrderno+'</Reference_No>'+CHR(13)+; 
    '<Customer_Ref>'+CustID+'</Customer_Ref>'+CHR(13)+; 
    '<Reference_3>'+lcname+'</Reference_3>'+CHR(13)+; 
    '<ExactID>'+lcExactID+'</ExactID>'+CHR(13)+; 
    '<Password>'+lcPassWd+ '</Password>'+CHR(13)+; 
    '<Card_Number>'+lncc_no+'</Card_Number>'+chr(13)+; 
    '</Transaction>' 
Hashme='POST'+chr(13)+'SOAP'+chr(13)+XMLRequest+chr(13)+lcDateTime+chr(13)+lcURL 
baseHash=STRCONV(Hashme, 13) 
loReq = Createobject('WinHttp.WinHttpRequest.5.1') 
loReq.SetTimeouts(2500, 2500, 2500, 2500) 
loReq.Open('POST', 'https://api-cert.payeezy.com/v1/transactions/v12', .F.) 
loReq.SetCredentials(lcExactID, lcPassWd , 0) 
loReq.SetRequestHeader('authorization', 'GGE4_API 14:'+lcKeyCode) 
loReq.SetRequestHeader('x-gge4-content-sha1',baseHash) 
loReq.SetRequestHeader('content-type', 'application/xml') 
loReq.SetRequestHeader('accept', 'text/xml') 
loReq.Send(XMLRequest)   
Xmltocursor(loReq.responsetext,'Payeezy') 
loReq="" 
+0

пожалуйста, прочитайте направляющие линии для размещения –

+0

@Uprightguy: вы должны рассмотреть ответы, которые были написаны для вас, проголосуйте за них, если они будут полезны, и примите ответ, который наиболее полезен. Это касается не только обратной связи с людьми, которые беспокоили ответ на ваш вопрос, но и для других людей, у которых может быть одна и та же проблема (чтобы они могли определить, полезны ли ответы или нет). – DarthGizka

ответ

1

Ваш код питания в base64 кодирование m.Hashme в заголовок authorization. Из того, что вы нам сказали, кажется, что вам нужно вычислить хэш SHA-1 m.Hashme и поместить хэш в заголовок (после кодировки base64).

Fox не имеет функции SHA-1, поэтому для этого вам нужен дополнительный источник. В Fox можно использовать Win32 CryptAPI, но это бесполезно грязно и довольно болезненно. Есть _crypt.vcx среди классов Foundation FoxPro (FFC), но это не очень помогает (и, как и все FFC, он не подходит для использования в любом случае).

Для чего это стоит, вот небольшой .prg, которые могут быть использованы для вычисления хэшей (по умолчанию: SHA1) с использованием Win32 CryptAPI и _crypt.vcx:

#include WinCrypt.h 

lparameters cData, nAlgorithmId 

with createobject([CCryptAPIWrapper_]) 
    return .Hash(@m.cData, m.nAlgorithmId) 
endwith 

******************************************************************************* 
* _CryptAPI.hProviderHandle needs to be hacked to PROTECTED or PUBLIC 
* and also most of the member functions called here 

define class CCryptAPIWrapper_ as _CryptAPI of _crypt.vcx 

    function Init 

     * declare missing CryptAPI functions 
     declare long CryptGetHashParam in WIN32API long, long, [email protected], [email protected], long 

     return dodefault() 

    procedure Destroy 

     if not empty(this.hProviderHandle) 
     this.CryptReleaseContext(this.hProviderHandle) 
     endif 

    function Hash (cData, nAlgorithmId) 

     nAlgorithmId = evl(m.nAlgorithmId, dnALG_SID_SHA) 

     local hHashContext, cHash 

     hHashContext = 0 
     cHash = .null. 
     try 
     this.CryptCreateHash(this.hProviderHandle, nAlgorithmId, 0, 0, @m.hHashContext) 
     this.CryptHashData(m.hHashContext, m.cData, len(m.cData), 0) 
     cHash = this.RetrieveHashFromContext(m.hHashContext) 
     finally 
     if not empty(m.hHashContext) 
      this.CryptDestroyHash(m.hHashContext) 
     endif 
     endtry 

     return m.cHash 

    function RetrieveHashFromContext (hHashContext) 

     local cHashSize, nXferSize 

     cHashSize = replicate(chr(0), 4) 
     nXferSize = len(m.cHashSize) 
     CryptGetHashParam(m.hHashContext, dnHP_HASHSIZE, @m.cHashSize, @m.nXferSize, 0) 

     assert m.nXferSize == 4 

     local nHashSize, cHashData 

     nHashSize = extract_UINT32_(m.cHashSize) 
     nXferSize = m.nHashSize 
     cHashData = space(m.nHashSize) 
     CryptGetHashParam(m.hHashContext, dnHP_HASHVAL, @m.cHashData, @m.nXferSize, 0) 

     assert m.nXferSize == m.nHashSize 

     return m.cHashData 

enddefine 

******************************************************************************* 
* note: BITOR() and BITLSHIFT() give a signed result -> can't use them here 

function extract_UINT32_ (s) 

    return asc(substr(m.s, 1, 1)) ; 
     + asc(substr(m.s, 2, 1)) * 0x100 ; 
     + asc(substr(m.s, 3, 1)) * 0x10000 ; 
     + asc(substr(m.s, 4, 1)) * 0x1000000 

До этого можно использовать, вам необходимо взломать _crypt.vcx, как указано в комментарии выше определения класса, потому что классlbbkk даже VFP9. Кроме того, путь поиска VFP должен включать как домашний каталог Fox, так и его подкаталог FFC.

+0

Что касается VFPEncryption.fll, похоже, имеет функцию SHA-1. http://www.sweetpotatosoftware.com/spsblog/2005/11/27/VFPEncryptionFLLUpdate.aspx – Uprightguy

+0

Есть тонны сторонних SHA-реализаций для Fox, и лично я бы выбрал действительно FLL в большинстве случаев. Однако в некоторых случаях может быть предпочтительнее не зависеть от дополнительных бинарных файлов, будь то библиотеки DLL, FLL, OCXen или еще что-то. YMMV. Для использования в производстве я бы избавился от '_crypt.vcx', хотя и скомпрометировал класс хэширования CryptAPI. '_crypt.vcx' является unsalvageable (как практически все, что поставляется с Fox или генерируется всем, что поставляется с ним). – DarthGizka

1

Я работаю над командой Payeezy в First Data. Я вижу, что в приведенном выше примере кода вы перепутали два наших API, наш REST API (https://api-cert.payeezy.com) и наш API на основе SOAP (api.demo.globalgatewaye4.firstdata.com)

Если вы используете REST API, то вот пример кода для генерации HMAC в PHP.

<?php 
$apiKey = "<your api key>"; 
$apiSecret = "<your consumer secret>"; 
$nonce = "<Crypographically strong random number>"; 
$timestamp = "<Epoch timestamp in milli seconds>"; 
$token = "<Merchant Token>"; 
$payload = "<For POST - Request body/For GET - empty string>"; 
$data = $apiKey + $nonce + $timestamp + $token + $payload; 
$hashAlgorithm = "sha256"; 

<!-- Make sure the HMAC hash is in hex --> 
$hmac = hash_hmac ($hashAlgorithm , $data , $apiSecret, false); 

<!-- Authorization : base64 of hmac hash --> 
$authorization = base64_encode($hmac); 
ehco $authorization; 
?> 

Если вы используете SOAP на основе API, вы найдете образец кода здесь: https://support.payeezy.com/hc/en-us/articles/203731149-API-Security-HMAC-Hash

+0

Можете ли вы дать мне лучший образец кода для мыла? Ссылка, которую они имеют, просто дает вам форму для ввода данных. Мне нужно знать формат полей, которые он ожидает в формате XML – Uprightguy

 Смежные вопросы

  • Нет связанных вопросов^_^