4

私はカールで私の深さから外れています。PayMill を自分のサイト (Perl で記述) に統合したいと考えています。Paymill 用の Perl ライブラリはまだないので、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 エラーで失敗します。これは、私が Curl をめちゃくちゃにしているために Paymill がキーを見つけられないためだと思います (-u が secret_key であると仮定します)。

ここで明らかな何かが欠けているように感じます。

誰かがこれを行う方法について正しい方向に私を向けることができますか? ありがとう

アップデート

すばらしい回答です。ご協力いただきありがとうございます。現在は機能しています。私は最終的に 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
}
4

3 に答える 3

4

他の回答と同様に、リクエストを実行するために LWP::UserAgent を使用することが最善の方法であると提案しています。

編集: PAYMILL はしばらく前からチャレンジ応答を送信しているため、コードを更新しました。

Paymill は RFC 2616 に準拠していないため、セクション 14.47 (API はチャレンジ応答を送信していません) LWP::UserAgent などは、資格情報を含む 2 番目の要求の送信に失敗しています。解決策は、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 で働いています。

于 2013-01-10T09:38:31.563 に答える
2

「レルム」が何であるかわからないため、ユーザー/パスワードとトークンを使用した認証部分が正しいかどうかはわかりません。それでも、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のドキュメントを少し読みました。それは言う:

認証

%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私が信じている部分がほぼ明確になります。

于 2013-01-09T15:55:21.923 に答える
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"
}
于 2013-01-09T17:24:39.470 に答える