在Perl中形成对PayMill的CURL请求

时间:2013-01-09 15:09:36

标签: perl curl paymill

我的卷曲深度。 我想将PayMill集成到我的站点(用Perl编写)。 Paymill还没有Perl lib,所以我需要通过curl连接到它们。

我已完成前端JS Paymill集成,并从PayMill收到付款令牌。

我现在需要将从Paymill收到的令牌传递给我的后端并使用curl要求PayMill完成交易并向用户收费。 此时我被困住了。

要进行交易,PayMill文档说我必须执行以下操作:

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

我相信-u是验证我的请求的Paymill密钥,虽然这里的文档不清楚。

我已经看过WWW :: Curl :: Easy,Net:Curl :: Easy和LWP :: Curl,但是这些方法的文档中没有任何内容让我明白如何构建上面的查询。

我已经尝试过(不相信它会起作用),只需在perl中编码一个字符串,如上所述;

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

然后将$ request传递给我的curl尝试,如下所示;

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;

但是因为Access Denied错误而失败,我认为这是因为Paymill没有找到我的密钥,因为我搞乱了Curl(假设-u应该是secret_key)。

我觉得我在这里遗漏了一些明显的东西。

有人能指出我正确的方向如何做到这一点? 感谢

UPDATE

优秀的答案,感谢大家的帮助,现在正在努力。我最终选择了Matthias的解决方案,最终的完整解决方案如下所示;

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
}

3 个答案:

答案 0 :(得分:4)

与其他答案一样,建议最好的方法是使用LWP :: UserAgent来处理请求。

修改:由于PAYMILL现在发送质询响应,我现在更新了代码。

由于Paymill不符合RFC 2616,第14.47节(API未发送质询响应)LWP :: UserAgent等类似用户无法使用凭据发送第二个请求。解决方案是“强制”LWP :: UserAgent通过将第一个请求添加为标头来发送凭据:

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"));

披露:我在Paymill工作。

答案 1 :(得分:2)

我不知道带有用户/密码和令牌的身份验证部分是否正确,因为我不知道'Realm'应该是什么。不过,请跟LWP一起去吧。这不是我不喜欢Curl,我只是不知道它,但我知道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;
}

修改:我在Paymill documentation中读到了一些内容。它说:

  

验证

     

实施例

     

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

     

要在Paymill API进行身份验证,您需要拥有自己的私钥   测试或真实账户。您必须使用http基本访问权限   认证。您的密钥必须设置为用户名。密码   不是必需的,您不必插入一个。但如果你想,感觉   可以自由插入任意字符串。

     

请注意

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

处理您商店的交易。       您的所有请求必须通过https进行。以另一种方式提出的请求将失败。这是出于安全考虑的原因   提交的数据。

还有http://en.wikipedia.org/wiki/HTTP_Secure的链接,我相信它会清除-u部分。

答案 2 :(得分:2)

您可以使用LWP::Protocol::Net::Curl来有机地集成LWP和libcurl 。检查一下:

#!/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;

输出:

* 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"
}