Ejegg has uploaded a new change for review. https://gerrit.wikimedia.org/r/230940
Change subject: Add Amazon API endpoint ...................................................................... Add Amazon API endpoint Sets and confirms order reference details. Bug: T108113 Change-Id: I9e36b5f3d77d57fec4a047df369c6802272a3421 --- M DonationInterface.php M amazon_gateway/amazon.adapter.php A amazon_gateway/amazon.api.php M amazon_gateway/amazon.js 4 files changed, 170 insertions(+), 9 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/DonationInterface refs/changes/40/230940/1 diff --git a/DonationInterface.php b/DonationInterface.php index bbd0223..1a014ce 100644 --- a/DonationInterface.php +++ b/DonationInterface.php @@ -80,6 +80,8 @@ // Amazon $wgAutoloadClasses['AmazonGateway'] = __DIR__ . '/amazon_gateway/amazon_gateway.body.php'; $wgAutoloadClasses['AmazonAdapter'] = __DIR__ . '/amazon_gateway/amazon.adapter.php'; +$wgAutoloadClasses['AmazonBillingApi'] = __DIR__ . '/amazon_gateway/amazon.api.php'; +$wgAPIModules['di_amazon_bill'] = 'AmazonBillingApi'; //Adyen $wgAutoloadClasses['AdyenGateway'] = __DIR__ . '/adyen_gateway/adyen_gateway.body.php'; diff --git a/amazon_gateway/amazon.adapter.php b/amazon_gateway/amazon.adapter.php index 8bc0a15..3c3c631 100644 --- a/amazon_gateway/amazon.adapter.php +++ b/amazon_gateway/amazon.adapter.php @@ -1,4 +1,8 @@ <?php + +use PayWithAmazon\Client as PwaClient; +use PayWithAmazon\ClientInterface as PwaClientInterface; + /** * Wikimedia Foundation * @@ -113,10 +117,15 @@ } public function doPayment() { - if ( $this->getData_Unstaged_Escaped( 'recurring' ) ) { - $resultData = $this->do_transaction( 'DonateMonthly' ); - } else { - $resultData = $this->do_transaction( 'Donate' ); + $resultData = new PaymentTransactionResponse(); + + try { + $this->confirmOrderReference(); + } catch ( ResponseProcessingException $ex ) { + $resultData->addError( + $ex->getErrorCode(), + $ex->getMessage() + ); } return PaymentResult::fromResults( @@ -125,6 +134,71 @@ ); } + /** + * Gets a Pay with Amazon client or facsimile thereof + * @return PwaClientInterface + */ + protected function getPwaClient() { + return new PwaClient( array( + 'merchant_id' => $this->account_config['SellerID'], + 'access_key' => $this->account_config['MWSAccessKey'], + 'secret_key' => $this->account_config['MWSSecretKey'], + 'client_id' => $this->account_config['ClientID'], + 'region' => $this->account_config['Region'], + 'sandbox' => $this->getGlobal( 'TestMode' ), + ) ); + } + + protected function confirmOrderReference() { + $client = $this->getPwaClient(); + + $orderReferenceId = $this->getData_Staged( 'order_reference_id' ); + + $setDetailsResult = $client->setOrderReferenceDetails( array( + 'amazon_order_reference_id' => $orderReferenceId, + 'amount' => $this->getData_Staged( 'amount' ), + 'currency_code' => $this->getData_Staged( 'currency_code' ), + 'seller_note' => WmfFramework::formatMessage( 'donate_interface-donation-description' ), + 'seller_order_reference_id' => $this->getData_Staged( 'order_id' ), + ) )->toArray(); + self::checkErrors( $setDetailsResult ); + + $confirmResult = $client->confirmOrderReference( array( + 'amazon_order_reference_id' => $orderReferenceId, + ) )->toArray(); + self::checkErrors( $confirmResult ); + + $getDetailsResult = $client->getOrderReferenceDetails( array( + 'amazon_order_reference_id' => $orderReferenceId, + ) )->toArray(); + self::checkErrors( $getDetailsResult ); + + $buyerDetails = $getDetailsResult['GetOrderReferenceDetailsResult']['OrderReferenceDetails']['Buyer']; + $email = $buyerDetails['Email']; + $name = $buyerDetails['Name']; + $nameParts = split( '/\s+/', $name, 2 ); // janky_split_name + $fname = $nameParts[0]; + $lname = isset( $nameParts[1] ) ? $nameParts[1] : ''; + $this->addRequestData( array( + 'email' => $email, + 'fname' => $fname, + 'lname' => $lname, + ) ); + } + + /** + * @throws ResponseProcessingException if response contains an error + * @param array $response + */ + static function checkErrors( $response ) { + if ( !empty( $response['Error'] ) ) { + throw new ResponseProcessingException( + $response['Error']['Message'], + $response['Error']['Code'] + ); + } + } + static function getCurrencies() { // See https://payments.amazon.com/sdui/sdui/about?nodeId=73479#feat_countries return array( diff --git a/amazon_gateway/amazon.api.php b/amazon_gateway/amazon.api.php new file mode 100644 index 0000000..de60cf3 --- /dev/null +++ b/amazon_gateway/amazon.api.php @@ -0,0 +1,56 @@ +<?php + +class AmazonBillingApi extends ApiBase { + protected $allowedParams = array( + 'orderReferenceId', + 'token', + ); + + public function execute() { + $orderReferenceId = $this->getParameter( 'orderReferenceId' ); + $adapter = new AmazonAdapter( array( 'api_request' => true ) ); + + if ( $adapter->checkTokens() ) { + $adapter->addRequestData( array( + 'order_reference_id' => $orderReferenceId, + ) ); + $result = $adapter->doPayment(); + if ( $result->getRefresh() ) { + $this->getResult()->addValue( + null, + 'errors', + $result->getErrors() + ); + } else { + $this->getResult()->addValue( + null, + 'success', + !$result->isFailed() + ); + } + } else { + // Don't let people continue if they failed a token check! + $this->getResult()->addValue( + null, + 'errors', + array( 'token-mismatch' => $this->msg( 'donate_interface-token-mismatch' )->text() ) + ); + } + } + + public function getAllowedParams() { + $params = array(); + foreach( $this->allowedParams as $param ) { + $params[$param] = null; + } + return $params; + } + + public function mustBePosted() { + return true; + } + + public function isReadMode() { + return false; + } +} diff --git a/amazon_gateway/amazon.js b/amazon_gateway/amazon.js index 98f11c2..7eaefed 100644 --- a/amazon_gateway/amazon.js +++ b/amazon_gateway/amazon.js @@ -9,7 +9,8 @@ loggedIn = false, loginError, accessToken, - billingAgreementId; + billingAgreementId, + orderReferenceId; // Cribbed from Amazon documentation function getURLParameter( name, source ) { @@ -92,12 +93,16 @@ new OffAmazonPayments.Widgets.Wallet( { sellerId: sellerId, onReady: function( billingAgreement ) { + // Will come in handy for recurring payments billingAgreementId = billingAgreement.getAmazonBillingAgreementId(); + }, + agreementType: 'OrderReference', + onOrderReferenceCreate: function( orderReference ) { + orderReferenceId = orderReference.getAmazonOrderReferenceId(); $( '#paymentContinue' ).show(); - $( '#paymentContinueBtn' ).off( 'click' ) + $( '#paymentContinueBtn' ).off( 'click' ); $( '#paymentContinueBtn' ).click( submitPayment ); }, - agreementType: 'BillingAgreement', design: { designMode: 'responsive' }, @@ -110,7 +115,31 @@ function submitPayment() { $( '#overlay' ).show(); - // TODO: make an API call - $( '#overlay' ).hide(); + var postdata = { + action: 'di_amazon_bill', + format: 'json', + orderReferenceId: orderReferenceId + }; + + $.ajax({ + url: mw.util.wikiScript( 'api' ), + data: postdata, + dataType: 'json', + type: 'POST', + success: function ( data ) { + $( '#overlay' ).hide(); + if ( data.errors ) { + // TODO: correctable error, let 'em correct it + } else if ( data.success ) { + // TODO: send donor to TY page, auth/capture money + } else { + // TODO: send donor to fail page + } + }, + error: function () { + $( '#overlay' ).hide(); + // TODO: handle when client can't talk to our own API! + } + }); } } )( jQuery, mediaWiki ); -- To view, visit https://gerrit.wikimedia.org/r/230940 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I9e36b5f3d77d57fec4a047df369c6802272a3421 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/DonationInterface Gerrit-Branch: payWithAmazon Gerrit-Owner: Ejegg <eeggles...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits