CURL PayMill Request Form in Perl

I come out of the depths with a curl. I want to integrate PayMill into my website (which is written in Perl). There is no Perl lib for Paymill yet, so I need to connect to them via curl.

I completed JS Paymill front-end integration and received a payment token from PayMill.

Now I need to transfer the token received from Paymill to my backend and use the curl to ask PayMill to complete the transaction and charge the user. At this moment I am stuck.

To make the transaction, the PayMill documentation says that I have to do the following:

curl https://api.paymill.de/v2/transactions \ -u b94a7550bd908877cbae5d3cf0dc4b74: \ -d "amount=4200" \ -d "currency=EUR" \ -d "token=098f6bcd4621d373cade4e832627b4f6" \ -d "description=Test Transaction" 

I believe this is a Paymill secret key to authenticate my request, although the documentation is not clear here.

I looked at WWW :: Curl :: Easy, Net: Curl :: Easy and LWP :: Curl, however, nothing in the documentation for these methods showed me how to form the request above.

I tried (not believing this would work) by simply encoding the string in perl, as described above;

 my $request = '-u ' . $private_key . " "; foreach my $key (keys %$params_in) { $request .= '-d "' . lc($key) .'='.$params_in->{$key} . ' '; } 

And then passing $ request to my attempt to curl like this:

 my $curl = WWW::Curl::Easy->new; $curl->setopt(WWW::Curl::Easy::CURLOPT_HEADER(), 1); $curl->setopt(WWW::Curl::Easy::CURLOPT_URL(), $paymill_server); $curl->setopt(WWW::Curl::Easy::CURLOPT_POST(), 1); $curl->setopt(WWW::Curl::Easy::CURLOPT_POSTFIELDS(), $request); my $response; $curl->setopt(WWW::Curl::Easy::CURLOPT_WRITEDATA(), \$response); my $retcode = $curl->perform; 

however, what about the Access Denied error, which I believe is an error because Paymill cannot find my key, because I am confusing Curl (assuming that -u should be secret_key).

I feel that something is missing here.

Can someone point me in the right direction how to do this? Thanks

UPDATE

Excellent answers, thank you all for your help, it is working now. In the end, I went with the Matthias solution, and the final complete transaction solution was as follows:

 use LWP::UserAgent; use MIME::Base64; use JSON::XS; my $ua = LWP::UserAgent->new; $ua->default_header(Authorization => "Basic " . encode_base64(private_key)); my $response = $ua->post(https://api.paymill.de:443/v2/transactions , $params ); if ( $response->is_success ) { my $obj = eval { decode_json $response->content } || {}; etc } 
+4
source share
3 answers

Like the other answers, the best way is to use LWP :: UserAgent to execute the requests.

Edit: Since PAYMILL is sending responses about responses, I have already updated the code.

Since Paymill does not comply with RFC 2616, section 14.47 (the API does not send a response to the request) LWP :: UserAgent and the like cannot send a second request with credentials. The solution is to force LWP :: UserAgent to send credentials with the first request, adding them as a header:

 use LWP::UserAgent; use MIME::Base64; my $ua = LWP::UserAgent->new; # Use the following line no longer: # $ua->default_header(Authorization => "Basic " . encode_base64("your PRIVATE key")) $ua->credentials('api.paymill.de:443', '', 'YOUR PRIVATE KEY'); # Dumping only use Data::Dumper; print Dumper($ua->get("https://api.paymill.de:443/v2/clients")); 

Disclosure: I work at Paymill.

+4
source

I don’t know if the user / password authentication part and your token are correct, since I don’t know what β€œRealm” is. However, go with the LWP . It's not that I don't like Curl, I just don't know that, but I know LWP.

 use strict; use warnings; use LWP::UserAgent; my $ua = LWP::UserAgent->new; $ua->credentials( 'api.paymill.de:80', 'Realm?', 'b94a7550bd908877cbae5d3cf0dc4b74' ); my $response = $ua->post( ' https://api.paymill.de/v2/transactions', { amount => "4200", currency => "EUR", token => "098f6bcd4621d373cade4e832627b4f6", description => "Test Transaction", } ); if ( $response->is_success ) { print $response->decoded_content; # or whatever } else { die $response->status_line; } 

Change I read a little in the Paymill documentation . It says:

Authentication

Example

% curl https://api.paymill.de/v2/clients \ -u e73fa5e7b87620585b5ea5d73c4d23bb:

To authenticate with the Paymill API, you need the secret key of your test or a real account. You must use basic HTTP authentication. Your key must be set as username. A password is not required and you do not need to insert it. But if you want, feel free to insert an arbitrary string.

Note

 Please keep your private keys secure and don't pass them to anybody. These private keys have extreme secure information for 

transaction processing of your store. All your requests must be made via https. Requests that will be made differently will fail. This is for safety reasons the data presented.

There is also a link to http://en.wikipedia.org/wiki/HTTP_Secure , which pretty much clears the -u part.

+2
source

You can use LWP :: Protocol :: Net :: Curl to organically combine LWP and libcurl. Check this:

 #!/usr/bin/env perl use common::sense; use Data::Printer; use JSON::XS; use LWP::Protocol::Net::Curl verbose => 1; use LWP::UserAgent; # create user agent my $ua = LWP::UserAgent->new; # POST request my $res = $ua->post( 'https://b94a7550bd908877cbae5d3cf0dc4b74:@api.paymill.de/v2/transactions', 'Accept-Encoding' => 'gzip', Content => { amount => 4200, currency => 'EUR', token => '098f6bcd4621d373cade4e832627b4f6', description => 'Test Transaction', }, ); # parse received data my $obj = eval { decode_json $res->content } // {}; # output p $obj; 

Output:

 * About to connect() to api.paymill.de port 443 (#0) * Trying 62.138.241.3... * Connected to api.paymill.de (62.138.241.3) port 443 (#0) * Connected to api.paymill.de (62.138.241.3) port 443 (#0) * successfully set certificate verify locations: * CAfile: /etc/ssl/certs/ca-certificates.crt CApath: none * SSL connection using RC4-SHA * Server certificate: * subject: OU=Domain Control Validated; OU=PositiveSSL Wildcard; CN=*.paymill.de * start date: 2012-07 * expire date: 2013-10 * subjectAltName: api.paymill.de matched * issuer: C=GB; S * SSL certificate verify ok. * Server auth using Basic with user 'b94a7550bd908877cbae5d3cf0dc4b74' > POST /v2/transactions HTTP/1.1 Authorization: Basic Yjk0YTc1NTBiZDkwODg3N2NiYWU1ZDNjZjBkYzRiNzQ6 User-Agent: libwww-perl/6.04 libcurl/7.28.0 OpenSSL/1.0.0e zlib/1.2.3.4 libidn/1.22 libssh2/1.2.8 Host: api.paymill.de Accept: */* Accept-Encoding: gzip Content-Length: 92 Content-Type: application/x-www-form-urlencoded * upload completely sent off: 92 out of 92 bytes < HTTP/1.1 200 OK < Server: nginx < Date: Wed, 09 Jan 2013 17:22:54 GMT < Content-Type: application/json < Transfer-Encoding: chunked < Connection: close < Set-Cookie: PHPSESSID=rmdo5a8c6u107gma28lotmmn24; path=/ < Expires: Thu, 19 Nov 1981 08:52:00 GMT < Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 < Pragma: no-cache < X-Server: hrtt-frn5-de13 < * Closing connection #0 Printing in line 28 of paymill.pl: \ { data { amount 4200, client { created_at 1357752174, description undef, email undef, id "client_85cb0bfc837f31c81015", payment [], subscription undef, updated_at 1357752174 }, created_at 1357752174, currency "EUR", description "Test Transaction", id "tran_c672daa0538e2a04e919", livemode false, origin_amount 4200, payment { card_holder undef, card_type "visa", client "client_85cb0bfc837f31c81015", country undef, created_at 1357752174, expire_month 12, expire_year 2014, id "pay_2732689f44928301c769", last4 1111, type "creditcard", updated_at 1357752174 }, preauthorization undef, refunds undef, status "closed", updated_at 1357752174 }, mode "test" } 
+2
source

All Articles