Using the Penny APIs
- IMPORTANT: production data cannot be sent to any non-production environment. All data sent to staging or other test environments must be “fake”
- The Penny API documentation is here Penny API
- All core Penny API’s can be leveraged using a PUT request to update or create records
- with the exception of our program API, a PUT request must include the unique ID of the record being created or updated as part of the endpoint
- example: to create or update a member in staging, you would use the following endpoint, where US1234 is the
member_id
of the recordhttps://api.staging.pennyapp.com/partner-api/v1/member/US1234
- We recommend leaving out any non-required payload keys when making requests if there is no value for the key (instead of sending a null or blank value)
- The header of requests must include an
Authorization
key, where the value isApi-Key <key here>
- note: a separate unique API key will be required per environment
- For basic Penny functionality, the member and order endpoints are required.
- Autoship data is only needed if applicable to the business model
- Product data is not explicitly required, and will be parsed from line items of order data
- Some API fields must adhere to standardized values. These include:
- Member Endpoint
- status
- options are:
active
inactive
terminated
pending_termination
- options are:
member_type
- options are:
downline
- Downline indicates someone who is a business builder and participating in a compensation plan
customer
- Customer indicates someone who has purchased, but is not building a business
prospect
- Prospect indicates someone who has never purchased before,is not building a business, and is a prospective customer or lead
- options are:
locale
- please provide a full culture code (example: es-US, es-MX, en-US)
country
- please use 2-digit ISO codes only (example: US, MX)
region
- please use ISO codes
- status
- Order Endpoint
order_type
- options are:
wholesale
returned
replacement
retail
autoship
- options are:
order_status
- options are:
processing
processed
shipped
cancelled
returned
failed
delivered
- options are:
currency_code
- please use ISO 3-digit codes (example: USD, CAD)
- Autoship Endpoint
autoship_status
- options are:
active
inactive
paused
- options are:
- Member Endpoint
Definitions
Penny Order Types | Definition |
---|---|
return | the order was returned for a refund |
replacement | the order was not refunded, and a replacement item(s) were sent |
wholesale | a single, one-time order (not associated with an autoship) |
retail | a single, one-time order placed from a retail flow or guest checkout |
autoship | an order that processed from an autoship template |
Penny Order Statuses | Definition |
---|---|
processing | typically used to indicate that the order has not shipped yet. this could also imply the order has not been fully paid for yet |
shipped | the order has shipped |
processed | the order has not shipped yet, but has been fully processed (paid for and ready to be shipped) |
cancelled | the order was never shipped and has been cancelled |
returned | the order was shipped to the customer and returned to the client for a refund |
failed | the order failed to process and has not shipped (this could be due to payment failure or system failures) |
delivered | the order has been delivered to the customer |
Using the Order endpoint
The API can be leveraged to support various business models. For most cases, Penny only requires a customer_member_id
and a seller_member_id
(with no other customer details). Please review each flow to determine how the API should be used for your business model.
Flow 1 - All orders are for “known” persons and all orders are attributed to the primary upline (only).
- This flow only requires sending order details and a
customer_member_id
(no seller or customer details) - When receiving order data, if the payload contains a
customer_member_id
and does NOT contain aseller_member_id
, then Penny will look for a correlating member record for that customer.- If a member record is found, Penny will determine if the primary upline of that customer is a Penny user. If yes, then Penny looks for an existing contact whose
member_id
matches the ordercustomer_member_id
- If no contact is found, a new contact is created and the order is mapped to the new contact record
- If an existing contact is found, then the order is mapped to the existing contact record for the user
- If a member record is found, Penny will determine if the primary upline of that customer is a Penny user. If yes, then Penny looks for an existing contact whose
IMPORTANT: This flow should not be used if the same customer has multiple unique member id’s that map to a single primary upline member ID. A contact will be created for each unique customer member ID, and will result in duplicate Penny contacts.
Example of when NOT to use this flow:
Every time Sarah places an order from Geoff, she gets a unique member id created for the order. Member IDs 1234, 5678, 45678 all belong to Sarah. Each member id is associated with the same primary upline, Geoff.
This would result in 3 contact records created for Sarah, all belonging to Geoff, which is not what we want. See Flow 3 for how to resolve this.
Flow 2 - All orders are for “known” persons and orders should only attribute to the seller of the order.
- This flow only requires sending order details, a
customer_member_id
and aseller_member_id
(nocustomer details
) - When receiving order data, if the payload contains a
customer_member_id
and also contains aseller_member_id
, then Penny will look for a correlating member record for that customer.- If a member record is found, Penny will determine if the seller is a Penny user. If yes, then Penny looks for an existing contact for the seller whose
member_id
matches the ordercustomer_member_id
- If no contact is found, a new contact is created and the order is mapped to the new contact record
- If an existing contact is found, then the order is mapped to the existing contact record for the user
- If a member record is found, Penny will determine if the seller is a Penny user. If yes, then Penny looks for an existing contact for the seller whose
Flow 3 - Orders may be for “unknown” persons with no unique member ID. Orders will only attribute to the seller of the order.
This flow may be ideal for guest checkouts or party planning business models, where there is not always a known customer_member_id
- Alternatively, if NO
customer_member_id
is provided in the order payload, then Penny relies on theseller_member_id
and thecustomer_details
data. In this flow, we leverage fuzzy matching to reduce duplicate contact records being generated for the same customer/seller relationship. - Penny will attempt to determine if there is an existing member record whose personal details match the
customer_details
in the order payload and whoseprimary_upline_member_id
matches the orderseller_member_id
- If a match is found, then Penny will update the order data
customer_member_id
to be themember_id
of the matching record. - If there is no existing contact found, or if the code cannot determine a precise match due to there being multiple records with the same matching score, then Penny will create a new member record that contains all the data in the order
customer_details
. Penny will assign the new member record an internalmember_id
. Additionally, Penny will map the ordercustomer_member_id
to the Penny-generatedmember_id
- If the
customer_details
on the order are a close match to an existing member record in the "api" database, then the fuzzy match would identify that record as being the correct match, and would not create any additional member records for that individual - If the
customer_details
on the order do NOT match any existing member record in the "api" database, then Penny would create a member record for them, and any subsequent orders sent to us with similar customer details would be identified as an existing member record
- If the
- If a match is found, then Penny will update the order data
Sample member payload
{ "first_name":"Mary", "last_name":"Tester", "city":"Gilbert", "region":"Arizona", "country":"US", "postal":"85296", "email":"useremail@gmail.com", "phone":"888-123-4567", "locale":"en-US", "status":"active", "website":"https://www.replicatedwebsite.com", "join_date":"2020-06-30", "join_time":"07:00:00", "member_id":"78793", "sponsor_member_id":"2993", "enroller_member_id":"2993", "has_access":true, "member_type":"customer", "address_line_1":"123 N That Way", "is_contactable":true }
Sample order payload
{ "order_id":"222221", "seller_member_id":"6785", "customer_member_id":"US1234", "order_type":"wholesale", "partner_order_type":"Replicated Site", "order_date":"2023-09-22", "order_time":"07:00:00", "order_display_date":"2023-09-22", "is_autoship":false, "autoship_id":"", "total":"432.13", "currency_code":"USD", "total_tax":"32.93", "total_discount":"0.00", "status":"shipped", "volume":"33.9800", "line_items":[ { "sku":"BCD012", "name":"Lotion 2 Pack", "unit_price":16.99, "unit_tax":null, "picture_url":"https://www.picturelink.com", "quantity":1, "volume":20.00, "line_item_id":5678, "parent_line_item_id":null }, { "sku":"ABC104", "name":"Luxury Lotion", "unit_price":19.99, "unit_tax":null, "picture_url":"https://www.picturelink.com", "quantity":2, "volume":null, "line_item_id":9987, "parent_line_item_id":5678 } ] }