Skip to content

Commit 933fbeb

Browse files
authored
Merge pull request #229 from EasyPost/migrate_partner_whitelabel
feat: migrates partner white label (referral) to GA
2 parents 1691a87 + 4e96ccb commit 933fbeb

13 files changed

+883
-59
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## NEXT RELEASE
44

55
- Adds support to pass `end_shipper_id` on the buy call of a Shipment
6+
- Migrates the Partner White Label (Referral) function from beta to the general library namespace and deprecates the beta functions
67

78
## v7.5.0 (2022-08-25)
89

easypost/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from easypost.pickup_rate import PickupRate
1818
from easypost.postage_label import PostageLabel
1919
from easypost.rate import Rate
20+
from easypost.referral import Referral
2021
from easypost.refund import Refund
2122
from easypost.report import Report
2223
from easypost.scanform import ScanForm

easypost/referral.py

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
from typing import (
2+
Any,
3+
Dict,
4+
List,
5+
Optional,
6+
)
7+
8+
import requests
9+
10+
from easypost.easypost_object import convert_to_easypost_object
11+
from easypost.error import Error
12+
from easypost.requestor import (
13+
RequestMethod,
14+
Requestor,
15+
)
16+
17+
18+
class Referral:
19+
@staticmethod
20+
def create(
21+
api_key: Optional[str] = None,
22+
**params,
23+
) -> Dict[str, Any]:
24+
"""Create a referral user.
25+
26+
This function requires the Partner User's API key.
27+
"""
28+
requestor = Requestor(local_api_key=api_key)
29+
new_params = {"user": params}
30+
response, api_key = requestor.request(
31+
method=RequestMethod.POST,
32+
url="/referral_customers",
33+
params=new_params,
34+
)
35+
return convert_to_easypost_object(response=response, api_key=api_key)
36+
37+
@staticmethod
38+
def update_email(
39+
email,
40+
user_id,
41+
api_key: Optional[str] = None,
42+
) -> bool:
43+
"""Update a referral user.
44+
45+
This function requires the Partner User's API key.
46+
"""
47+
requestor = Requestor(local_api_key=api_key)
48+
url = f"/referral_customers/{user_id}"
49+
wrapped_params = {
50+
"user": {
51+
"email": email,
52+
}
53+
}
54+
_, _ = requestor.request(
55+
method=RequestMethod.PUT,
56+
url=url,
57+
params=wrapped_params,
58+
)
59+
60+
# Return true if succeeds, an error will be thrown if it fails
61+
return True
62+
63+
@staticmethod
64+
def all(
65+
api_key: Optional[str] = None,
66+
**params,
67+
) -> List:
68+
"""Retrieve a list of referral users.
69+
70+
This function requires the Partner User's API key.
71+
"""
72+
requestor = Requestor(local_api_key=api_key)
73+
response, api_key = requestor.request(
74+
method=RequestMethod.GET,
75+
url="/referral_customers",
76+
params=params,
77+
)
78+
return convert_to_easypost_object(response=response, api_key=api_key)
79+
80+
@staticmethod
81+
def add_credit_card(
82+
referral_api_key: str,
83+
number: str,
84+
expiration_month: int,
85+
expiration_year: int,
86+
cvc: str,
87+
primary_or_secondary: str = "primary",
88+
) -> Dict[str, Any]:
89+
"""Add credit card to a referral user.
90+
91+
This function requires the Referral User's API key.
92+
"""
93+
easypost_stripe_api_key = Referral._retrieve_easypost_stripe_api_key()
94+
95+
try:
96+
stripe_token = Referral._create_stripe_token(
97+
number, expiration_month, expiration_year, cvc, easypost_stripe_api_key
98+
)
99+
except Exception:
100+
raise Error(message="Could not send card details to Stripe, please try again later")
101+
102+
response = Referral._create_easypost_credit_card(
103+
referral_api_key,
104+
stripe_token.get("id", ""),
105+
priority=primary_or_secondary,
106+
)
107+
return convert_to_easypost_object(response)
108+
109+
@staticmethod
110+
def _retrieve_easypost_stripe_api_key() -> str:
111+
"""Retrieve EasyPost's Stripe public API key."""
112+
requestor = Requestor()
113+
public_key, _ = requestor.request(
114+
method=RequestMethod.GET,
115+
url="/partners/stripe_public_key",
116+
)
117+
return public_key.get("public_key", "")
118+
119+
@staticmethod
120+
def _create_stripe_token(
121+
number: str,
122+
expiration_month: int,
123+
expiration_year: int,
124+
cvc: str,
125+
easypost_stripe_key: str,
126+
) -> Dict[str, Any]:
127+
"""Get credit card token from Stripe."""
128+
headers = {
129+
# This Stripe endpoint only accepts URL form encoded bodies
130+
"Content-type": "application/x-www-form-urlencoded",
131+
}
132+
133+
credit_card_dict = {
134+
"card": {
135+
"number": number,
136+
"exp_month": expiration_month,
137+
"exp_year": expiration_year,
138+
"cvc": cvc,
139+
}
140+
}
141+
142+
form_encoded_params = Requestor.form_encode_params(credit_card_dict)
143+
url = "https://api.stripe.com/v1/tokens"
144+
145+
stripe_response = requests.post(
146+
url,
147+
params=form_encoded_params,
148+
headers=headers,
149+
auth=requests.auth.HTTPBasicAuth(easypost_stripe_key, ""),
150+
)
151+
return stripe_response.json()
152+
153+
@staticmethod
154+
def _create_easypost_credit_card(
155+
referral_api_key: str,
156+
stripe_object_id: str,
157+
priority: str = "primary",
158+
) -> Dict[str, Any]:
159+
"""Submit Stripe credit card token to EasyPost."""
160+
requestor = Requestor(local_api_key=referral_api_key)
161+
162+
params = {
163+
"credit_card": {
164+
"stripe_object_id": stripe_object_id,
165+
"priority": priority,
166+
}
167+
}
168+
169+
response, _ = requestor.request(
170+
method=RequestMethod.POST,
171+
params=params,
172+
url="/credit_cards",
173+
)
174+
return response

tests/cassettes/test_beta_referral_add_credit_card.yaml

Lines changed: 202 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)