PayPal
モバイルの今後の支払い(エンドツーエンドアプリケーション)
サーチ…
備考
この例は、ノードサーバーを使用してAndroidデバイスからPayPalの将来の支払いを作成する実践的な例を示しています。
Androidのステップ1:レイアウト、初期化、およびハンドリングサーバーの応答
このアプリケーション(Android +ノードサーバー)のサンプルコードは、 PayPal DeveloperのGithubリポジトリにあります 。
アプリケーションのAndroid部分を作成する最初の段階は、基本レイアウトを設定し、ノードで設定するサーバーから返された応答を処理することです。
まず、新しいPayPalConfigurationオブジェクトを作成してアプリケーション情報を格納します。
private static PayPalConfiguration config = new PayPalConfiguration()
.environment(PayPalConfiguration.ENVIRONMENT_SANDBOX)
.clientId("YOUR APPLICATION CLIENT ID")
.merchantName("My Store")
.merchantPrivacyPolicyUri(Uri.parse("https://www.example.com/privacy"))
.merchantUserAgreementUri(Uri.parse("https://www.example.com/legal"));
次に、簡単なボタンをonCreate(...)に追加して支払いの開始を行います。これは単にアクションをトリガーすることであり、ユーザーの将来の支払いを作成するための開始プロセスとして配置する必要があります(たとえば、サブスクリプションに同意した場合など)。
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button button = (Button) findViewById(R.id.paypal_button);
}
res > layout > activity_main.xml下で、ボタンの定義を関連付けられたアクションとともに追加します。クリックするとbeginFuturePayment(...)コールされます。これは1分以内に定義します。
<Button android:id="@+id/paypal_button"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/paypal_button"
android:onClick="beginFuturePayment" />
res > values > strings.xmlで、ボタンの文字列参照を追加します。
<string name="paypal_button">Process Future Payment</string>
ここで、ボタンハンドラを追加して、ユーザがボタンをクリックしたときに将来の支払い処理を開始する呼び出しを開始します。ここでは、この例の一番上に設定した設定オブジェクトで支払いサービスを開始します。
public void beginFuturePayment(View view){
Intent serviceConfig = new Intent(this, PayPalService.class);
serviceConfig.putExtra(PayPalService.EXTRA_PAYPAL_CONFIGURATION, config);
startService(serviceConfig);
Intent intent = new Intent(this, PayPalFuturePaymentActivity.class);
intent.putExtra(PayPalService.EXTRA_PAYPAL_CONFIGURATION, config);
startActivityForResult(intent, 0);
}
将来の支払いを行うための呼び出しが開始されると、サーバーに送信する必要がある情報が表示されます。有効な将来の支払い要求( authCodeとmetadataId )からこの情報を抽出し、サーバーに非同期要求を実行して、将来の支払いを完了させます(手順2で詳しく説明します)。
@Override
protected void onActivityResult (int requestCode, int resultCode, Intent data){
if (resultCode == Activity.RESULT_OK){
PayPalAuthorization auth = data.getParcelableExtra(PayPalFuturePaymentActivity.EXTRA_RESULT_AUTHORIZATION);
if (auth != null){
try{
//prepare params to be sent to server
String authCode = auth.getAuthorizationCode();
String metadataId = PayPalConfiguration.getClientMetadataId(this);
String [] params = {authCode, metadataId};
//process async server request for token + payment
ServerRequest req = new ServerRequest();
req.execute(params);
} catch (JSONException e) {
Log.e("FPSample", "JSON Exception: ", e);
}
}
} else if (resultCode == Activity.RESULT_CANCELED) {
Log.i("FPSample", "User canceled.");
} else if (resultCode == PayPalFuturePaymentActivity.RESULT_EXTRAS_INVALID) {
Log.i("FPSample", "Invalid configuration");
}
}
最後に、 onDestroy()を定義します。
@Override
public void onDestroy(){
stopService(new Intent(this, PayPalService.class));
super.onDestroy();
}
Androidのステップ2:非同期サーバーリクエスト
このアプリケーション(Android +ノードサーバー)のサンプルコードは、 PayPal DeveloperのGithubリポジトリにあります 。
この時点でPayPalの未払いの支払いボタンがクリックされました.PayPal SDKからの認証コードとメタデータIDがあり、将来の支払い処理を完了するために、これらの情報をサーバーに渡す必要があります。
以下のバックグラウンドプロセスでは、いくつかのことを行っています。
- 私たちは、私たちのサーバ用のURIを
http://10.0.2.2:3000/fpstoreに設定しました。これはlocalhost上で実行されているサーバの/fpstoreエンドポイントに当たっています。 - 送信されるJSONオブジェクトが設定され、認証コードとメタデータIDが含まれます。
- 接続が行われます。リクエストが成功した場合(200/201の範囲)、サーバーから応答が返されることが期待できます。私たちはその応答を読み、それを返します。
- 最後に、返されたサーバー文字列を処理する
onPostExecute(...)メソッドが設定されています。この例の場合、単にログに記録されます。
public class ServerRequest extends AsyncTask<String, Void, String> {
protected String doInBackground(String[] params){
HttpURLConnection connection = null;
try{
//set connection to connect to /fpstore on localhost
URL u = new URL("http://10.0.2.2:3000/fpstore");
connection = (HttpURLConnection) u.openConnection();
connection.setRequestMethod("POST");
//set configuration details
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Accept", "application/json");
connection.setAllowUserInteraction(false);
connection.setConnectTimeout(10000);
connection.setReadTimeout(10000);
//set server post data needed for obtaining access token
String json = "{\"code\": \"" + params[0] + "\", \"metadataId\": \"" + params[1] + "\"}";
Log.i("JSON string", json);
//set content length and config details
connection.setRequestProperty("Content-length", json.getBytes().length + "");
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
//send json as request body
OutputStream outputStream = connection.getOutputStream();
outputStream.write(json.getBytes("UTF-8"));
outputStream.close();
//connect to server
connection.connect();
//look for 200/201 status code for received data from server
int status = connection.getResponseCode();
switch (status){
case 200:
case 201:
//read in results sent from the server
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null){
sb.append(line + "\n");
}
bufferedReader.close();
//return received string
return sb.toString();
}
} catch (MalformedURLException ex) {
Log.e("HTTP Client Error", ex.toString());
} catch (IOException ex) {
Log.e("HTTP Client Error", ex.toString());
} catch (Exception ex) {
Log.e("HTTP Client Error", ex.toString());
} finally {
if (connection != null) {
try{
connection.disconnect();
} catch (Exception ex) {
Log.e("HTTP Client Error", ex.toString());
}
}
}
return null;
}
protected void onPostExecute(String message){
//log values sent from the server - processed payment
Log.i("HTTP Client", "Received Return: " + message);
}
}
Androidのステップ3:ノードサーバーでアクセストークンとプロセスの支払いを取得する
このアプリケーション(Android +ノードサーバー)のサンプルコードは、 PayPal DeveloperのGithubリポジトリにあります 。
ステップ2から、 /fpstoreエンドポイントのサーバーに認証コードとメタデータIDを渡す非同期要求が行われました。要求を完了し、将来の支払いを処理するためにトークンを交換する必要があります。
まず、設定変数とオブジェクトを設定します。
var bodyParser = require('body-parser'),
http = require('http'),
paypal = require('paypal-rest-sdk'),
app = require('express')();
var client_id = 'YOUR APPLICATION CLIENT ID';
var secret = 'YOUR APPLICATION SECRET';
paypal.configure({
'mode': 'sandbox',
'client_id': client_id,
'client_secret': secret
});
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json());
これで、Androidコードから/fpstoreエンドポイントに送信されたPOSTリクエストをリッスンするExpressルートを設定しました。
私たちはこのルートでいくつかのことをしています:
- POST本体から認証コードとメタデータIDを取得します。
- 次に、
generateToken()メソッドにコードオブジェクトを渡してリクエストします。成功すると、支払いを作成するために使用できるトークンが取得されます。 - 次に、設定オブジェクトが作成される将来の支払いに対して作成され、
payment.create(...)への要求が行われ、将来の支払いおよび支払い設定オブジェクトに沿って渡されます。これにより、将来の支払いが作成されます。
app.post('/fpstore', function(req, res){
var code = {'authorization_code': req.body.code};
var metadata_id = req.body.metadataId;
//generate token from provided code
paypal.generateToken(code, function (error, refresh_token) {
if (error) {
console.log(error);
console.log(error.response);
} else {
//create future payments config
var fp_config = {'client_metadata_id': metadata_id, 'refresh_token': refresh_token};
//payment details
var payment_config = {
"intent": "sale",
"payer": {
"payment_method": "paypal"
},
"transactions": [{
"amount": {
"currency": "USD",
"total": "3.50"
},
"description": "Mesozoic era monster toy"
}]
};
//process future payment
paypal.payment.create(payment_config, fp_config, function (error, payment) {
if (error) {
console.log(error.response);
throw error;
} else {
console.log("Create Payment Response");
console.log(payment);
//send payment object back to mobile
res.send(JSON.stringify(payment));
}
});
}
});
});
最後に、サーバーを作成してポート3000で待機するようにします。
//create server
http.createServer(app).listen(3000, function () {
console.log('Server started: Listening on port 3000');
});