/
akolonin
/
aigents-java
Обзор
Документация
Войти
/
akolonin
/
aigents-java
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/main/java/net/webstructor/comm/paypal/PayPal.java
231 строка
8 KB
Anton Kolonin
3.1.9 Sync/async Reporter for social reports based on Searcher template
19 дек 2020, 15:17
19 дек 2020, 15:17
d113d4d
Код
Авторство
О чём код?
/* * MIT License * * Copyright (c) 2005-2020 by Anton Kolonin, Aigents® * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.webstructor.comm.paypal; import java.io.IOException; import java.io.StringReader; import java.util.Collection; import java.util.Date; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; import javax.json.Json; import javax.json.JsonArray; import javax.json.JsonObject; import javax.json.JsonReader; import net.webstructor.agent.Body; import net.webstructor.al.AL; import net.webstructor.al.Time; import net.webstructor.al.Writer; import net.webstructor.comm.HTTP; import net.webstructor.comm.Socializer; import net.webstructor.core.Environment; import net.webstructor.core.Thing; import net.webstructor.data.SocialFeeder; import net.webstructor.data.Translator; import net.webstructor.peer.Peer; import net.webstructor.peer.Profiler; import net.webstructor.util.JSON; import net.webstructor.util.MapMap; import net.webstructor.util.ReportWriter; //TODO: merge PayPal+PayPaler? public class PayPal extends Socializer { String appId; String appSecret; public static final String monthly = "monthly"; public static final String yearly = "yearly"; transient MapMap payments = new MapMap(); //all latest cached trasactions transient private ReentrantLock busy = new ReentrantLock(); public PayPal(Body body, String appId, String appSecret) { super(body); this.appId = appId; this.appSecret = appSecret; } @Override public String name(){ return "paypal"; } String base_url() { return body.self().getString(Body.paypal_url,"https://api.paypal.com"); } static String auth_url(String base_url) { return base_url + "/v1/oauth2/token"; } static String payment_url(String base_url) { return base_url + "/v1/payments/payment/"; } public static Date updateTerm(Date term, Date paid, String type) { if (paid != null) { if (term == null || term.compareTo(paid) <= 0) term = paid; if (type != null && type.toLowerCase().startsWith(yearly)) return Time.addYears(term, 1); else return Time.addMonths(term, 1); } return term; } public void updatePeerTerm(String id, Date term) { try { Collection peers = body.storager.getByName(Body.paypal_id, id); if (!AL.empty(peers)) ((Thing)peers.iterator().next()).setString(Peer.paid_term,Time.day(term, false)); } catch (Exception e) { body.error("PayPal no id "+id,e); } } public void updatePeerTerm(String id, Date paid, String type) { try { Collection peers = body.storager.getByName(Body.paypal_id, id); if (!AL.empty(peers) && peers.size() == 1) { Thing peer = (Thing)peers.iterator().next(); Date term = Time.day(peer.getString(Peer.paid_term)); term = updateTerm(term, paid, type); peer.setString(Peer.paid_term,Time.day(term, false)); } else body.error("PayPal no unique peer id "+id,null); } catch (Exception e) { body.error("PayPal no peer id "+id,e); } } public static String token(Environment body, String auth_url, int timeout, String client_id, String client_secret) throws IOException { //https://www.paypal.com/apex/developer/expressCheckout/getAccessToken String auth_base64 = HTTP.auth_base64(client_id,client_secret); body.debug("PayPal request grant_type=client_credentials "+auth_base64); String response = HTTP.simple(auth_url,"grant_type=client_credentials","POST",timeout,null,new String[][] { {"Accept", "application/json"}, {"Accept-language", "en_US"}, {"Authorization",auth_base64}, {"Content-Type", "application/x-www-form-urlencoded"} }); body.debug("PayPal response "+response); JsonReader jsonReader = Json.createReader(new StringReader(response)); JsonObject json = jsonReader.readObject(); return HTTP.getJsonString(json,"access_token"); } @Override public void resync(long sinceTimemillis) { try { if (busy.tryLock(60L, TimeUnit.SECONDS)) { updateCache(sinceTimemillis); busy.unlock(); } else body.debug("PayPal crawling skip"); } catch (Exception e) { body.error("PayPal crawling resync error", e); } } private void updateCache(long blockOrTimemillis) { try { int timeout = 0;//TODO String access_token = PayPal.token(body, PayPal.auth_url(base_url()), timeout, appId, appSecret); String next_id = null; for (;;) { //https://developer.paypal.com/docs/api/get-an-access-token-curl/ //https://developer.paypal.com/docs/api/payments/v1/#payment_list //https://developer.paypal.com/docs/integration/direct/payments/search-payment-details/ String request = "?count=20&sort_by=create_time"; if (next_id != null) request += "&start_id="+next_id; body.debug("PayPal request "+request+" "+access_token); String response = HTTP.simple(PayPal.payment_url(base_url())+request,null,"GET",timeout,null,new String[][] { {"Accept", "application/json"}, {"Accept-language", "en_US"}, {"Content-Type", "application/json"}, {"Authorization","Bearer "+access_token} }); body.debug("PayPal response "+response); JsonReader jsonReader = Json.createReader(new StringReader(response)); JsonObject json = jsonReader.readObject(); JsonArray payobjects = JSON.getJsonArray(json, "payments"); next_id = JSON.getJsonString(json, "next_id"); if (payments != null) for (int i = 0; i < payobjects.size(); i++) { PayPalItem item = new PayPalItem(payobjects.getJsonObject(i)); if (item.valid()) { Object found = payments.getObject(item.payer_id, item.date, false); String description_ex = item.description + " " + item.total + " " + item.currency; body.debug("Spidering peer paypal "+found+" "+item.payer_id+" "+item.date+" "+description_ex); if (found == null) payments.putObject(item.payer_id, item.date, description_ex); else { next_id = null;//weh have reached the top in the cache break; } } } if (AL.empty(next_id)) break; }//pagination } catch (Exception e) { body.error("PayPal resync", e); } } @Override public SocialFeeder getFeeder(String id, String token, String key, Date since, Date until, String[] areas) throws IOException{ PayPalFeeder feeder = new PayPalFeeder(body,this,id,body.languages,since,until); feeder.getFeed(token, since, until, new StringBuilder());//updates feeder.term behind the scenes if (feeder.term != null) updatePeerTerm(id,feeder.term); return feeder; } protected void reportPeer(ReportWriter rep, Translator t, SocialFeeder feeder,String title, String user_id, String name, String surname, java.util.Set options, int minPercent, int minCount, Object[][] cross_peers) { String payments = Writer.capitalize(t.loc("payments")); rep.initPeer(user_id, Writer.capitalize(name), Writer.capitalize(surname), payments, feeder.since(), feeder.until()); rep.table("payments",payments, t.loc(new String[]{"Period",null,null,"Number",payments}), feeder.getFriendsPeriods(),0,0); Object[][] details; if (!AL.empty(details = feeder.getDetails())) rep.table("payments",payments, t.loc(new String[]{"Date",null,null,payments,null,null}), details,0,0); rep.closePeer(); } @Override public Profiler getProfiler(Thing peer) { return new Profiler(body,this,peer,Body.paypal_id,Body.paypal_token,Body.paypal_key); } }