In order for this site to work correctly we need to store a small file (called a cookie) on your computer. Most every site in the world does this, however since the 25th of May 2011, by law we have to get your permission first. Please abandon the forum if you disagree.

Para que este foro funcione correctamente es necesario guardar un pequeño fichero (llamado cookie) en su ordenador. La mayoría de los sitios de Internet lo hacen, no obstante desde el 25 de Marzo de 2011 y por ley, necesitamos de su permiso con antelación. Abandone este foro si no está conforme.

Integracion de App YPF - API Azure (Solucionado)

Foro público de Xailer en español
ryder1912
Posts: 17
Joined: Thu Jul 09, 2015 8:17 pm

Integracion de App YPF - API Azure (Solucionado)

Postby ryder1912 » Tue Sep 17, 2019 11:09 pm

Buenas a todos. Estamos realizando la integracion de xailer con la api de YPF (Azure) pero tenemos problemas con el POST, la integracion consta de 2 procedimientos:

1 - Intencion de Pago (POST):

Code: Select all

POST /api/private/payment_intentions
 {   "provider_id": “​YPF351576293dhf9b50ugfyy4crrhb32qz73w​”,  // ​Identity unívoco de la intención de pago, lo envía el PDV para su seguimiento
     "amount": ​30​, ​//Monto total de la operación. [opcional]   
     "products": [ ​  //Siempre array tiene que contener por lo menos una posición   
      {       
        “id_price_book”: “​432​” // id price book (String, Opcional)     
        “description”: “​pepsi​ ​500cm​”, //requerido     
         "quantity": ​1​, //requerido (1/99)     
         "type": ​"store"​, //valores opessa_store, opessa_fuel, opessa_boxes       
         "unit_price": ​30​,       
         "amount": ​30, //opcional se calcula pxq     
       }   
     ],   
     "fuel_station_id": ​3344​, //Apies   "point_of_sale": ​44637​, //ID del punto de Venta 
      "sale_type": ​"store"​, 
       "meta_data":[ "provider_creation_date": ​"2019-01-17T17:09:45.664Z"​,  //Momento del envío del mensaje desde el PDV     
                             "provider_delivery_date": ​"2019-01-17T17:09:45.664Z"​,   //Momento del envío del mensaje desde el YPF Central  ]
}
 


Como respuesta nos devuelve un 201 - OK con el id de Pago (payment_id), ademas de otros datos. Con ese id se hace una consulta del pago

2 - Consulta del pago realizado (GET)
GET /api/private/payment_intentions/{payment_id}

Como decia el problema lo tenemos en el POST, al realizar el OpenRequest nos devuelve el siguiente error:

Code: Select all

----------------------- Información detallada del error -----------------------

      Subsistema: BASE
 Código de error: 1004
          Estado: .F.
     Descripción: Message not found
       Operación: TINTERNET:OPENREQUEST
      Argumentos:
         Fichero:
 Código error SO: 0

Pila de llamadas:
  TFORM1:BTNBMP1CLICK (78)
  TBTNBMP:ONCLICK (0)
  TBTNBMP:CLICK (100)
  (b)XCONTROL:XCONTROL (148)
  TBTNBMP:COMMAND (0)
  TSCROLLINGWINCONTROL:WMCOMMAND (282)
  TFORM1:WMCOMMAND (943)
  RUNFORM (0)
  TAPPLICATION:RUN (276)
  MAIN (15)


Datos de las credenciales y endpoints para la integración

API URL: https://ypfamepcjqa.azure-api.net/mspayments/api/

SECURITY HEADERS
X-ACCESS-TOKEN : 65f76c1a-8475-407c-9f6c-ecd724fca025
Ocp-Apim-Subscription-Key : 8f12b920f95f4e5da21499b317c48b29

OTROS HEADERS
Content-Type : application/json

Aqui dejo el codigo completo y tambien para descargarlo:
APPYPF.zip
(51.24 KiB) Downloaded 10 times

Code: Select all

#include "Xailer.ch"
#include "ExStruct.ch"
#include "hbxml.ch"
#include "WinINet.api"

CLASS TForm1 FROM TForm

   COMPONENT oBtnBmp1
   COMPONENT oMemo1
   COMPONENT oBtnBmp2

   DATA cAPIURL             INIT 'https://ypfamepcjqa.azure-api.net/mspayments/api'
   DATA cAccessToken     INIT '65f76c1a-8475-407c-9f6c-ecd724fca025'
   DATA cKey                  INIT '8f12b920f95f4e5da21499b317c48b29'

   METHOD CreateForm()
   METHOD BtnBmp1Click( oSender )
   METHOD BtnBmp2Click( oSender )

ENDCLASS

#include "MenuPrincipal.xfm"

//------------------------------------------------------------------------------
// POST
METHOD BtnBmp1Click( oSender ) CLASS TForm1
LOCAL cJson, cDatos:='', cData, debug:=''
LOCAL cTexto, oInternet, xerror, Connection, File

   cTexto:=''
BEGIN SEQUENCE
   oInternet:= TInternet():New( Self )
   oInternet:nPort := INTERNET_DEFAULT_HTTPS_PORT
   oInternet:nTimeOut:= 60000
   IF !oInternet:Open()
      BREAK "Not Open"
   ENDIF
   Connection:= oInternet:Connect(::cAPIURL)
   IF !Connection
      BREAK "Not Connection"
   ENDIF
      cJson:='{'
      //datos de ejemplo
      cDatos+='"provider_id": "YPF351576293dhf9b50ugfyy4crrhb32qz73w",' //ID ingresa del PDV
      cDatos+='"amount": 30,'                                           //monto total opcional
      cDatos+='"products": [{'
      cDatos+='"id_price_book": "432",'                                 // string opcional
      cDatos+='"description": "50n litros de combustible",'
      cDatos+='"quantity": 26.70,'                                     //decimal
      cDatos+='"type": "fuel",'                                          //store,fuel,boxes
      cDatos+='"code": "Infinia",'                                      //Infinia, Disel, etc
      cDatos+='"unit_price": 30,'
      cDatos+='"title": "product title",'
      cDatos+='"amount": 30}],'                                       //opcional se calcula pxq
      cDatos+='"fuel_station_id": 4321,'                          //id unico de cada QR
      cDatos+='"point_of_sale": 1,'                                 //si es null se enviaYVOSAPP
      cDatos+='"fuel_pump": "1",'
      cDatos+='"fuel_dispenser": "1",'
      cDatos+='"provider_external_gateway_id": "432",'
      cDatos+='"sale_type": "GAS_FLOW",'
      cDatos+='"meta_data": [{'
      cDatos+='"provider_creation_date":"2019-01-17T17:09:45.664Z",'   //envio desde el PDV
      cDatos+='"provider_delivery_date":"2019-01-17T17:09:45.664Z"}]' //envio desde el YPF central
      cDatos+='}'
      cJson+=cDatos     
         
   debug:=::cAPIURL+"/private/payment_intentions/Ocp-Apim-Subscription-Key:"+::cKey+"/X-ACCESS-TOKEN:"+::cAccessToken
   
   File:= oInternet:OpenRequest("POST",::cAPIURL+"/private/payment_intentions/Ocp-Apim-Subscription-Key:"+::cKey+"/X-ACCESS-TOKEN:"+::cAccessToken,INTERNET_FLAG_SECURE,"HTTP/1.0")
   IF !oInternet:SendRequest(File, "Content-type: application/json", cJson )
      BREAK "Not SendRequest"
   ENDIF
   cTexto:=''
   WHILE oInternet:ReadFile( File, @cData, 65536 )
       cTexto += cData
   ENDDO
   cTexto += " *** "+oInternet:GetErrorDescription()+" "+HB_NToS(oInternet:nLastError)+" "+HB_NToS(GetLastError())

   ::oMemo1:Value:= cTexto
   RECOVER USING xerror
     xerror:= oInternet:GetErrorDescription()
   MsgInfo( xerror )
END SEQUENCE

RETURN Nil

//------------------------------------------------------------------------------
// GET
METHOD BtnBmp2Click( oSender ) CLASS TForm1
LOCAL hRequest, cBuffer := Space( 1024 ), cData := ""
LOCAL cUrl1:='/payment_intentions/1'
LOCAL debug:=''

      WITH OBJECT TInternet():Create()
         IF :Open()
             debug:=:GetErrorDescription(:nLastError())
              IF !Empty( hRequest := :OpenURL(::cAPIURL+cUrl1) )
                  WHILE :ReadFile( hRequest, @cBuffer, 65536 )
                   cData += cBuffer
                  ENDDO
               :CloseURL( hRequest )
              ENDIF
         ENDIF
         debug:=:GetErrorDescription(:nLastError())
         :Close()
         ::oMemo1:Value:= cData
      END
RETURN Nil


Otro ejemplo de POST pero con Curl, devuelve error de Acceso Denegado...

Code: Select all

curl -X POST \
  https://ypfamepcjqa.azure-api.net/mspayments/api/private/payment_intentions \
  -H 'Content-Type: application/json' \
  -H 'Ocp-Apim-Subscription-Key: 8f12b920f95f4e5da21499b317c48b29' \
  -H 'X-ACCESS-TOKEN: 65f76c1a-8475-407c-9f6c-ecd724fca025' \
  -d '{
    "provider_id": "1234",
    "products": [
        {
            "id": "432",
            "id_price_book": "432",
            "description": "28 litros de combustible",
            "quantity": 28,
            "type": "fuel",
            "code": "INFINIA",
            "unit_price": 40
        }
    ],
"fuel_station_id": XXX,
"fuel_pump": " XXX ",
"fuel_dispenser": "XXX",
"point_of_sale": XXX ,
    "sale_type": "GAS_FLOW"
}'


Espero que puedan ayudar. slds.
Last edited by ryder1912 on Sat Oct 05, 2019 3:59 am, edited 1 time in total.
ryder1912
Posts: 17
Joined: Thu Jul 09, 2015 8:17 pm

Re: Integracion de App YPF

Postby ryder1912 » Wed Sep 25, 2019 1:53 am

Buenas a todos. Hemos probado algunas configuraciones pero toavia no hemos podido hacer funcionar el POST. Nos sigue dando error en el oInternet:OpenRequest. No sabemos que es lo que estamos haciendo mal.

Code: Select all


 DATA cAPIURL          INIT 'http://ypfamepcjqa.azure-api.net/mspayments/api'
 DATA cAccessToken  INIT '65f76c1a-8475-407c-9f6c-ecd724fca025'
 DATA cKey               INIT '8f12b920f95f4e5da21499b317c48b29'
   
METHOD BtnBmp1Click( oSender ) CLASS TForm1
LOCAL cJson, cDatos:='', cData, debug:='', cURL2
LOCAL cTexto, oInternet, xerror, Connection, File

   cTexto:=''
BEGIN SEQUENCE
   oInternet:= TInternet():New( Self )
   oInternet:nPort := INTERNET_DEFAULT_HTTPS_PORT
   oInternet:nTimeOut:= 60000
   IF !oInternet:Open()
      BREAK "Not Open"
   ENDIF
   Connection:= oInternet:Connect(::cAPIURL)
   IF !Connection
      BREAK "Not Connection"
   ENDIF
      cJson:='{'
      //datos de ejemplo
      cDatos+='"provider_id": "YPF351576293dhf9b50ugfyy4crrhb32qz73w",' //ID ingresa del PDV
      cDatos+='"amount": 30,'                                           //monto total opcional
      cDatos+='"products": [{'
      cDatos+='"id_price_book": "432",'                                 // string opcional
      cDatos+='"description": "50n litros de combustible",'
      cDatos+='"quantity": 26.70,'                                     //decimal
      cDatos+='"type": "fuel",'                                          //store,fuel,boxes
      cDatos+='"code": "Infinia",'                                       //Infinia, Disel, etc
      cDatos+='"unit_price": 30,'
      cDatos+='"title": "product title",'
      cDatos+='"amount": 30}],'                                         //opcional se calcula pxq
      cDatos+='"fuel_station_id": 1559,'                                //id unico de cada QR
      cDatos+='"point_of_sale": 1,'                                 //si es null se enviaYVOSAPP
      cDatos+='"fuel_pump": "1",'
      cDatos+='"fuel_dispenser": "1",'
      cDatos+='"provider_external_gateway_id": "432",'
      cDatos+='"sale_type": "GAS_FLOW",'
      cDatos+='"meta_data": ['
      cDatos+='"provider_creation_date":"2019-01-17T17:09:45.664Z",'   //envio desde el PDV
      cDatos+='"provider_delivery_date":"2019-01-17T17:09:45.664Z"]' //envio desde el YPF central
      cDatos+='}'
      cJson+=cDatos
 
   File:= oInternet:OpenRequest("POST",::cAPIURL+"/private/payment_intentions/?Ocp-Apim-Subscription-Key="+::cKey+"&X-ACCESS-TOKEN="+::cAccessToken,INTERNET_FLAG_SECURE,"HTTP/1.0")
   //IF !oInternet:SendRequest(File, "Content-type: application/json", cJson )

   IF !oInternet:SendRequest(File,"Ocp-Apim-Subscription-Key:8f12b920f95f4e5da21499b317c48b29,X-ACCESS-TOKEN:65f76c1a-8475-407c-9f6c-ecd724fca025,content-type:application/json", cJson )

      BREAK "Not SendRequest"
   ENDIF
   cTexto:=''
   WHILE oInternet:ReadFile( File, @cData, 65536 )
       cTexto += cData
   ENDDO
   cTexto += " *** "+oInternet:GetErrorDescription()+" "+HB_NToS(oInternet:nLastError)+" "+HB_NToS(GetLastError())

   ::oMemo1:Value:= cTexto
   RECOVER USING xerror
     xerror:= oInternet:GetErrorDescription()
   MsgInfo( xerror )
END SEQUENCE

RETURN Nil


Tambien probamos enviar un POST con el POSTMAN y fciona ya que nos devuelve el id del pago. Dejo la respuesta y las imagenes del POST (con POSTMAN)
Este es el response (respuesta) con los datos de la venta. Slds

Code: Select all

{
    "data": {
       [color=#FF0000] "id": 500315, // ID del PAGO[/color]
        "amount": 771,
        "sub_total": 771,
        "fuel_station_id": 1559,
        "buyer_email": null,
        "buyer_dni": null,
        "products": [
            {
                "id": 0,
                "quantity": 25.7,
                "done": 0,
                "type": "fuel",
                "code": "Infinia",
                "unit_price": 30,
                "amount": 771,
                "title": "product title",
                "description": "50n litros de combustible",
                "pictureurl": null,
                "category": null,
                "id_price_book": "433"
            }
        ],
        "fuel_pump": 1,
        "point_of_sale": 1,
        "creation_date": "2019-09-24T05:24:05.263",
        "delivery_date": null,
        "is_paid": false,
        "is_active": false,
        "payment_intention_geohash": "4xb52gpj1",
        "payment_intention_latitude": -45.8176,
        "payment_intention_longitude": -67.45735,
        "is_pre_purchase": false,
        "universal_id": null,
        "creation_timestamp": 1569302645100,
        "sale_type": "GAS_FLOW",
        "network": "OLEUM",
        "payment_intention_status": 4,
        "serviclub_id": null,
        "fuel_dispenser": 1,
        "full_name": null,
        "qr_provider": null,
        "serviclub_card": null,
        "validation_time_response": 0,
        "initialize_time_response": 0.0228,
        "validation_eess_time_response": 4.3298000000000005,
        "search_payment_intention_time_response": 62.787800000000004,
        "initialize_merge_time_response": 0.0207,
        "search_fuel_station_time_response": 0.0092,
        "search_products_time_response": 0,
        "updated_date": "2019-09-24T14:27:19.9928443+00:00",
        "device_serial": null,
        "device_uuid": null,
        "device_manufacturer": null,
        "device_model": null,
        "device_platform": null,
        "device_version": null,
        "context_creation_time_response": 98.07300000000001,
        "provider_id": "YPF351576293dhf9b50ugfyy4crrhb32qz73w",
        "meta_data": {},
        "payment_id": null,
        "error_owner": null,
        "error_category": null,
        "error_code": null,
        "error_description": null,
        "fuel_station_request": null,
        "fuel_station_response": null,
        "payment_intention_internal_status": 0,
        "provider_external_gateway_id": null
    },
    "time_response": 432
}
Attachments
05 -ok.png
05 -ok.png (24.81 KiB) Viewed 322 times
01 -POST.png
01 -POST.png (24.34 KiB) Viewed 322 times
ryder1912
Posts: 17
Joined: Thu Jul 09, 2015 8:17 pm

Re: Integracion de App YPF

Postby ryder1912 » Sat Oct 05, 2019 3:54 am

Buenas a todos. Aca esta la solucion. By Emilio A.
Slds.

Post

Code: Select all

METHOD BtnBmp1Click( oSender ) CLASS TForm1
LOCAL cJson, cDatos:='', cData, debug:='', cURL2
LOCAL cTexto, oInternet, xerror, Connection, File, oWinHttp
Local cFechaAct:= transf(DToS(Date()),'@R 9999-99-99')+'T'+time()+'Z'

cTexto:=''
BEGIN SEQUENCE
   oInternet:= TInternet():New( Self )
   oInternet:nPort := INTERNET_DEFAULT_HTTPS_PORT
   oInternet:nTimeOut:= 60000
   IF !oInternet:Open()
      BREAK "Not Open"
   ENDIF
   Connection:= oInternet:Connect(::cAPIURL)
   IF !Connection
      BREAK "Not Connection"
   ENDIF
      cJson:='{'
      //datos de ejemplo
      cDatos+='"provider_id": "YPF351576293dhf9b50ugfyy4crrhb32qz73w",'
      cDatos+='"amount": 30,'                                         
      cDatos+='"products":[{'
      cDatos+='"id_price_book": "432",'                               
      cDatos+='"description": "50n litros de combustible",'
      cDatos+='"quantity": 26.70,'                                   
      cDatos+='"type": "fuel",'                                         
      cDatos+='"code": "Infinia",'                                     
      cDatos+='"unit_price": 30,'
      cDatos+='"title": "product title",'
      cDatos+='"amount": 30'
      cDatos+='}],'                                       
      cDatos+='"fuel_station_id": 1111,'                         
      cDatos+='"point_of_sale": 1,'                               
      cDatos+='"fuel_pump": "1",'
      cDatos+='"fuel_dispenser": "1",'
      cDatos+='"provider_external_gateway_id": "432",'
      cDatos+='"sale_type": "GAS_FLOW"'
      cDatos+= '"meta_data":[{'
      cDatos+= '"provider_creation_date":"'+cFechaAct+'"'
      cDatos+='},'
      cDatos+='{"provider_delivery_date":"'+cFechaAct+'"}'
      cDatos+=']}'
      cDatos+='}'
      cJson+=cDatos

oWinHttp := CreateObject( "MSXML2.serverXMLHTTP.6.0" )
oWinHttp:open("POST",::cAPIURL,.f.)
oWinHttp:SetRequestHeader("content-type","application/json")
oWinHttp:SetRequestHeader("X-ACCESS-TOKEN","65f76c1a-8475-407c-9f6c-ecd724fca025")
oWinHttp:SetRequestHeader("Ocp-Apim-Subscription-Key","8f12b920f95f4e5da21499b317c48b29")

oWinHttp:send(cJson)
::oMemo1:Value =+ oWinHttp:ResponseText
::oMemo2:Value := oWinHttp:Status
END SEQUENCE

RETURN Nil


Este es el Get - (Con el post se obtiene el Id del Pago)

Code: Select all

METHOD BtnBmp2Click( oSender ) CLASS TForm1
LOCAL hRequest, cBuffer := Space( 1024 ), cData := ""
LOCAL cUrl1:='/payment_intentions/500314' 
LOCAL debug:='' ,oWinHttp

        oWinHttp := CreateObject( "MSXML2.serverXMLHTTP.6.0" )
   oWinHttp:open("GET",::cAPIURL,.f.)
   oWinHttp:SetRequestHeader("content-type","application/json")
   oWinHttp:SetRequestHeader("X-ACCESS-TOKEN","65f76c1a-8475-407c-9f6c-ecd724fca025")
        oWinHttp:send()

::oMemo1:Value =+ oWinHttp:ResponseText
::oMemo2:Value := oWinHttp:Status

RETURN Nil
Claudio C
Posts: 47
Joined: Sun Sep 20, 2015 8:13 pm
Location: Buenos Aires

Re: Integracion de App YPF - API Azure (Solucionado)

Postby Claudio C » Sun Oct 06, 2019 2:46 pm

Gracias emilio por compartirlo.

Return to “Spanish”