We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 6534
    • 8 Posts
    hi,

    I’m having a problem with a curl script when I use it inside of Modx. Are there any good tutorials on using curl with Modx?

    My script works fine outside of Modx but when I call as a snippet it fails to work.

    thanks,
    Dan

    The code bellow works fine on its own called from the same server.

    <?php
    if (!defined(’MPI_PASSWORD’))
    {
    define(’MPI_PASSWORD’, ’P@ssw0rd’);
    }
    function get_xml_children($values, &$i)
    {
    $children = array();

    if ($i > -1 && isset($values[$i][’value’]))
    {
    $children[’_value_’] = $values[$i][’value’];
    }

    while (++$i < count($values))
    {
    $type = $values[$i][’type’];

    if ($type === ’cdata’)
    {
    $children[’_value_’] .= $values[$i][’value’];
    }
    elseif ($type === ’complete’ || $type === ’open’)
    {
    $name = $values[$i][’tag’];
    $tag = get_xml_tag($values[$i], $values, $i, $type);
    $children[$name][] = $tag;
    }
    elseif ($type === ’close’)
    {
    break;
    }
    }

    // Collapse single tags?
    foreach($children as $key => $value)
    {
    if (is_array($value) && count($value) === 1)
    {
    $children[$key] = $value[0];
    }
    }

    return $children;
    }

    function get_xml_tag($thisvalues, $values, &$i, $type)
    {
    $tag = array();

    if (isset($thisvalues[’attributes’]))
    {
    $tag[’_attributes_’] = $thisvalues[’attributes’];
    }

    if ($type === ’complete’)
    {
    if (isset($thisvalues[’value’]))
    {
    $tag[’_value_’] = $thisvalues[’value’];
    }
    }
    else
    {
    $tag = array_merge($tag, get_xml_children($values, $i));
    }

    return $tag;
    }

    function get_xml_tree($data)
    {
    $parser = xml_parser_create();
    xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false);
    xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, true);
    xml_parse_into_struct($parser, $data, $values);
    xml_parser_free($parser);

    $i = -1;
    return get_xml_children($values, $i);
    }

    function xml_entities($str)
    {
    return strtr($str, array(
    ’&’ => ’&amp;’,
    ’"’ => ’&quot;’,
    ’\’’ => ’&apos;’,
    ’<’ => ’&lt;’,
    ’>’ => ’&gt;’));
    }
    $SiteSecureBaseURL = $_SERVER[’SCRIPT_URI’];
    // Function to construct the XML that is required to query the enrollment status with the MPI.
    //Settings
    $totalPrice = ’1.23’;
    $acquirerBIN=’123456’;
    $currencyCode=’826’;
    $merchantID=’123456789012345’;
    $transactionNarrative=’120’;
    $XID=’12345678901234567890’;
    function get_enrollment_xml()
    {
    global $acquirerBIN, $currencyCode, $merchantID, $transactionNarrative, $XID, $totalPrice;

    $xml = ’<?xml version="1.0" encoding="UTF-8"?>’;
    $xml .= ’<Request>’;
    $xml .= ’<Enrollment>’;
    $xml .= ’<AcquirerBIN>’.xml_entities($acquirerBIN).’</AcquirerBIN>’;
    $xml .= ’<Amount>’.xml_entities($totalPrice).’</Amount>’;
    $xml .= ’<CurrencyCode>’.xml_entities($currencyCode).’</CurrencyCode>’;
    $xml .= ’<ExpiryDateMonth>’.xml_entities(’12’).’</ExpiryDateMonth>’;
    $xml .= ’<ExpiryDateYear>’.xml_entities(’2012’).’</ExpiryDateYear>’;
    $xml .= ’<MerchantID>’.xml_entities($merchantID).’</MerchantID>’;
    $xml .= ’<PAN>’.xml_entities(’4123450131003312’).’</PAN>’;
    $xml .= ’<Password>’.xml_entities(MPI_PASSWORD).’</Password>’;
    $xml .= ’<TransactionNarrative>’.xml_entities($transactionNarrative).’</TransactionNarrative>’;
    $xml .= ’<XID>’.xml_entities($XID).’</XID>’;
    $xml .= ’</Enrollment>’;
    $xml .= ’</Request>’;
    $curl = curl_init();
    //header ("content-type: text/xml");
    curl_setopt($curl, CURLOPT_HTTPHEADER, array("content-type: text/xml"));
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $xml);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); // FIXME This should really be true if local host has appropriate root certificate
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // FIXME This should really be true if local host has appropriate root certificate
    curl_setopt($curl, CURLOPT_URL, ’https://testmpi.cardeasexml.com’);

    $result = curl_exec($curl);

    curl_close($curl);

    return $result;
    }

    //session_start();

    $enrollment_xml = get_xml_tree(get_enrollment_xml());

    // Store the POST and XML response data in the session.
    // Associate it with the Merchant Data identifier being sent to the Access Control Server.
    // For the purposes of this example the Merchant Data identifier is a random number created in this script.
    $md = rand();
    $_SESSION[’MD’.$md][’enrollment_xml’] = $enrollment_xml;

    // If the card holder is not enrolled processing stops.
    // The CardHolderEnrolled should mapped and sent to CardEaseXML with a TransactionStatus of ’None’.
    if (!isset($enrollment_xml[’Response’][’Enrollment’][’CardHolderEnrolled’][’_value_’]) ||
    $enrollment_xml[’Response’][’Enrollment’][’CardHolderEnrolled’][’_value_’] != ’Y’)
    {
    echo get_enrollment_xml();
    //return $output ;
    }
    // The card holder is enrolled so they should be redirected to the Access Control Server.
    // The Access Control Server requires MD, PaReq and TermUrl fields.
    // The MD field can be empty if required.
    else
    {
    //$TransactionStatus = ’yes’;
    echo get_enrollment_xml();
    //echo $TransactionStatus;

    //return $output ;
    }
    ?>
      • 897
      • 1,620 Posts
      so, what is the error message you are get?
        "Und wenn du lange in einen Abgrund blickst, blickt der Abgrund auch in dich hinein."

        Не используйте Revo для "просто сайтов". Используйте Evo

        Who can defeat the Russian bear?
        • 21257 MODX Staff
        • 730 Posts
        When you declare variables in a snippet, I don’t believe that they are in the global namespace. At least, not until the eval() has finished.. I’m not quite sure of the details there. But I just tried a small test to confirm the following advice, and it seems sound.

        So in your function call, when you
        global $acquirerBIN, $currencyCode, $merchantID, $transactionNarrative, $XID, $totalPrice;
        

        , you’re not getting access to variables you want.

        Try explicitly putting those variables in the global namespace, e,g.
        $GLOBALS['totalPrice'] = '1.23';
        $GLOBALS['acquirerBIN']='123456';
        $GLOBALS['currencyCode']='826';
        $GLOBALS['merchantID']='123456789012345';
        $GLOBALS['transactionNarrative']='120';
        $GLOBALS['XID']='12345678901234567890';
        

        Or if you don’t want to force those into the global namespace, then pass them into the function in a different way.
          Mike Schell
          Lead Developer, MODX Cloud
          Email: [email protected]
          GitHub: https://github.com/netProphET/
          Twitter: @mkschell
          • 6534
          • 8 Posts
          Hi,

          I’ve included the two XML responses the first an error response from the Modx one and the correct response from the php page called as a direct URL. I’m guessing the server is not receiving well formed XML when the call is made from the Modx snippet

          The error (when called from the Modx snippet:

          <?xml version="1.0" encoding="utf-8" ?>
          - <Response>
          - <Error>
          <Code>CEMPI-BadRequest</Code>
          <Detail>The ’AcquirerBIN’ element is invalid - The value ’’ is invalid according to its datatype ’String’ - The Pattern constraint failed.</Detail>
          <Message>Your browser (or proxy) sent a request that this server could not understand.</Message>
          </Error>
          </Response>

          Same code called from the server as php page:

          <?xml version="1.0" encoding="utf-8" ?>
          - <Response>
          - <Enrollment>
          <AccessControlServerURL>https://acs.gpayments.com:443/acs/pa/0/MVvh4CpymUdUiXUXSJxFVq0CAAA0/</AccessControlServerURL>
          <PayerAuthenticationRequest>eJxVUttugkAQ/RXCe90bCphxG6ptahOsbaHpK1kmSiOgC9bL13dXoZe3OWcm58ycXbg9lhvnC3VT1NXEZQPqOlipOi+q1cRNk4ebwL2VkKw14uwN1V6jhBibJluhU+QTd5m94o5xn/l+KOiIh8wTIvSHLBChGHoBHQnBXQnLyMxJ6JykMRpwID00klqts6qVkKnd3XwhGRfecASkg1Cins861g9CeqmAXGmoshJlgk3r9EJALhyoel+1+iQDbsR6AHu9keu23Y4JORwOA6UxL1qVbTYDVZdAbBvI707Lva0aI3cschkn8/NilvLFeTWMZ/en+PzCFp/Ke06iCRA7AXnWouSUUepx6rDRmLKxZxa48JCVdg+TARfmwCuArfWIuo5t/CXABK/Nu/R39AjwuK0rNBMmzJ8acmyUEaHG0FZAfg+YPtqIVWtSi9+/1t50eyrTPC0+0o+3p+PD+45OoyiiNvjLkHUoTGSMs6uFBUCsDOnelHT/wVT//sk37TrDXQ==</PayerAuthenticationRequest>
          <CardHolderEnrolled>Y</CardHolderEnrolled>
          </Enrollment>
          </Response>
            • 6534
            • 8 Posts
            Thanks netProphET,

            Brilliant, very grateful, that seems to be the problem - I’ve just hard coded the values and it worked!

            I’ll try your method for scoping the globals next.

            Thanks again,
            Dan