Introduction
Porch’s Partner Project APIs enable partners to generate and submit project requests to Porch on behalf of their customers.
Environments
Environment | Domain | Needs whitelist? | Purpose |
---|---|---|---|
production |
api.porch.com |
No | Porch’s production environment |
qa |
api.qa.porch.com |
Yes | Porch QA and testing environment. |
Authentication
Porch APIs that expose sensitive information or actions will require authentication. Porch will give each partner a unique API key, which we will use to verify the your identity and limit your access to data. Please keep your API keys secret.
This is an example of an authorized request.
$ curl -H 'X-Auth-Token: {your_api_key}' 'https://api.qa.porch.com/retail/project/5f391449-f6a0-454d-9a55-d81959862480'
All API calls must be made over HTTPS, to ensure that your authentication token remains secret. Calls made over plain HTTP will fail. You must authenticate for each request.
If a request requires authentication and you didn’t provide a valid token, we will respond with HTTP error code 403
(Forbidden).
Api Response Wrappers
All Partner Project endpoints return Porch API Responses.
Success
On success, response data can be extracted from the body
property and error
will be null
.
Example Success Response
{
"body": {
"serviceCode": "FURNITURE_LARGE",
"serviceFamilyCode": "FURNITURE",
"projectScopeQuestion": "How many pieces are included in the set?",
"projectScopeAnswers": [
"1",
"1-3",
"2-4",
"4-6",
"5-6",
"7+"
],
"availability": true,
"estimatedPrice": {
"min": 150,
"max": 910
}
},
"error": null
}
Errors
On failure, the body
will be null and the error
property will contain information about the cause of the error.
The code reflects the HTTP response status and the message provides a human-readable explanation of the error, if available.
HTTP Status | code | Meaning |
---|---|---|
400 | badRequest | The request was not readable or failed validation. For example, a required value was not provided. |
401 | unauthorized | Authentication is required and has failed or has not yet been provided. |
403 | forbidden | The request did not contain a valid X-Auth-Token header, or the token was not recognized. |
404 | notFound | The requested resource could not be found. |
500 | serverError | An unexpected error occurred. This may be a temporary glitch, in which case attempting to re-send the request may succeed, or it may be a programming error requiring manual intervention. |
Example Failure Responses
{
"body": null,
"error": {
"code": "badRequest",
"message": "Invalid serviceCode BLAH",
"validationErrors":[]
}
}
{
"body": null,
"error": {
"code": "unauthorized",
"message": "HTTP 401 Unauthorized",
"validationErrors":[]
}
}
Validation Errors
Validation errors are a special type of error response in which the validationErrors array will contain one entry for each missing or invalid value detected in the request object.
The field
property refers to the name of the offending property of the request object and the
message property indicates the nature of the problem or the action that may be taken to correct it.
Example Validation Error Response
{
"body": null,
"error": {
"code": "validationError",
"message": "",
"validationErrors": [
{
"field": "customer.firstName",
"message": "customer.firstName is required"
},
{
"field": "address",
"message": "address is required"
}
]
}
}
Response Status Codes
Porch uses conventional HTTP response codes to indicate success or failure of an API request.
In general, codes in the 2xx
range indicate success,
codes in the 4xx
range indicate an error that resulted from the provided information
(e.g. a required parameter was missing, a booking failed, etc.),
and codes in the 5xx
range indicate an error with Porch’s servers.
Service and Trade Ontology API
Key Concepts
The Ontology API should be invoked from partner back-end services, and will require the X-Auth-Token
header as described in Authentication above.
List Services
GET /partner/ontology/service/list
curl 'https://api.qa.porch.com/partner/ontology/service/list'
Example response (shortened)
{
"body": [
{
"id": 5052,
"name": "Exterior Painting",
"description": "The application of paint coatings to the exterior surfaces of a home",
"actorSingular": "Exterior Painting",
"actorPlural": "Exterior Painting",
"seoUrlPart": "exterior-painting"
},
{
"id": 5134,
"name": "Interior Painting",
"description": "The application of paint coatings to the interior rooms and surfaces of a home",
"actorSingular": "Interior Painting",
"actorPlural": "Interior Painting",
"seoUrlPart": "interior-painting"
}
],
"error": null
}
Fetch a list of all supported service types.
List Trades
GET /partner/ontology/trade/list
curl -H 'X-Auth-Token: {your_api_key}' 'https://api.qa.porch.com/partner/ontology/trade/list'
Example Response (shortened)
{
"body": [
{
"id": 1171,
"name": "Painters",
"description": "Painters",
"actorSingular": "Painter",
"actorPlural": "Painters",
"seoUrlPart": "painters"
},
{
"id": 1180,
"name": "Plumbers",
"description": "Plumbers",
"actorSingular": "Plumber",
"actorPlural": "Plumbers",
"seoUrlPart": "plumbers"
}
],
"error": null
}
Fetch a list of all supported trades.
Find Service Type By Query
GET partner/ontology/service-type/semantic-search/{query}
curl -H 'X-Auth-Token: {your_api_key}' 'https://api.qa.porch.com/partner/ontology/service-type/semantic-search/fix%20my%20roof'
Example Response
{
"body": [
{
"serviceTypeKey": "565",
"serviceTypeName": "Roofing Services",
"score": 0.20066754644016344,
"rank": 1
},
{
"serviceTypeKey": "6380",
"serviceTypeName": "Single Ply Roofing Repair",
"score": 0.1396348052935329,
"rank": 2
},
{
"serviceTypeKey": "827",
"serviceTypeName": "Roofing Repair",
"score": 0.12129595951023495,
"rank": 3
},
{
"serviceTypeKey": "6377",
"serviceTypeName": "Asphalt Shingle Roofing Repair",
"score": 0.08246634125154534,
"rank": 4
},
{
"serviceTypeKey": "6385",
"serviceTypeName": "Tile Roofing Repair",
"score": 0.05140449185122803,
"rank": 5
}
],
"error": null
}
Provides the five most relevant service types, ranked, along with a score that conveys a level of confidence in the match.
Find Pro Type and Service Type By Query
GET /partner/ontology/semantic-search/{query}
curl -H 'X-Auth-Token: {your_api_key}' 'https://api.qa.porch.com/partner/ontology/semantic-search/Fix%20my%20roof'
Example Response
{
"body": {
"proTypeRankings": [
{
"proTypeKey": "1199",
"proTypeName": "Roofers",
"score": 0.8312032442746927,
"rank": 1
},
{
"proTypeKey": "1109",
"proTypeName": "Handyman",
"score": 0.09934016737773564,
"rank": 2
},
{
"proTypeKey": "1100",
"proTypeName": "General Contractors",
"score": 0.021309438256283064,
"rank": 3
},
{
"proTypeKey": "1193",
"proTypeName": "Remodeling Contractors",
"score": 0.009193742258043614,
"rank": 4
},
{
"proTypeKey": "1171",
"proTypeName": "Painters",
"score": 0.0038368425802040463,
"rank": 5
}
],
"serviceTypeRankings": [
{
"serviceTypeKey": "565",
"serviceTypeName": "Roofing Services",
"score": 0.20066754644016344,
"rank": 1
},
{
"serviceTypeKey": "6380",
"serviceTypeName": "Single Ply Roofing Repair",
"score": 0.1396348052935329,
"rank": 2
},
{
"serviceTypeKey": "827",
"serviceTypeName": "Roofing Repair",
"score": 0.12129595951023495,
"rank": 3
},
{
"serviceTypeKey": "6377",
"serviceTypeName": "Asphalt Shingle Roofing Repair",
"score": 0.08246634125154534,
"rank": 4
},
{
"serviceTypeKey": "6385",
"serviceTypeName": "Tile Roofing Repair",
"score": 0.05140449185122803,
"rank": 5
}
],
"version": "semantics-0.5.16881-8rsr9"
},
"error": null
}
Provides the five most relevant trades and service types, ranked, along with a score that conveys a level of confidence in the match.
Related Services
GET /partner/ontology/related-services/by-seo-url/{seoUrl}
curl -H 'X-Auth-Token: {your_api_key}' 'https://api.qa.porch.com/partner/ontology/related-services/by-seo-url/painters'
GET /partner/ontology/related-services/service/{serviceId}
curl -H 'X-Auth-Token: {your_api_key}' 'https://api.qa.porch.com/partner/ontology/related-services/service/584'
GET /partner/ontology/related-services/trade/{tradeId}
curl -H 'X-Auth-Token: {your_api_key}' 'https://api.qa.porch.com/partner/ontology/related-services/trade/1171'
Example response (shortened)
{
"body": [
{
"id": 584,
"name": "Painting",
"description": "The services related to the application of interior or exterior paint coatings",
"actorSingular": "Painting",
"actorPlural": "Painting",
"seoUrlPart": "painting"
},
{
"id": 5052,
"name": "Exterior Painting",
"description": "The application of paint coatings to the exterior surfaces of a home",
"actorSingular": "Exterior Painting",
"actorPlural": "Exterior Painting",
"seoUrlPart": "exterior-painting"
},
{
"id": 5134,
"name": "Interior Painting",
"description": "The application of paint coatings to the interior rooms and surfaces of a home",
"actorSingular": "Interior Painting",
"actorPlural": "Interior Painting",
"seoUrlPart": "interior-painting"
}
],
"error": null
}
Find Related Services by SEO URL
Fetch a set of services related to the given service or trade.
Find Related Services by Service ID
Fetch a set of services related to the given service.
Find Related Services by Trade ID
Fetch a set of services related to the given trade.
Partner Project API
Key Concepts
The Porch Partner Project API should be invoked from partner back-end services, and will require the X-Auth-Token
header as described in Authentication above.
List of a User’s Projects
GET /partner/project/list/by-contact-info
$ curl -H 'X-Auth-Token: {your_api_key}' 'https://api.qa.porch.com/partner/project/list/by-contact-info?emailAddress=homeowner@gmain.com'
Example Response
{
"body": [
{
"projectId": "15dfc685-59ae-4d09-902a-d20518736c65",
"partnerKey": 65,
"partnerOrderId": "123xyz",
"acquisitionKey": 2619,
"status": "REQUIREMENTS_GATHERING",
"serviceKey": 6544,
"serviceSku": "PCH111",
"locationKey": 1174224427,
"userKey": 202260
},
{
"projectId": "de0c4337-21a2-4550-adb3-348d14ebd7a0",
"partnerKey": 65,
"partnerOrderId": "123123123123123",
"acquisitionKey": 338,
"status": "COMPANY_MATCHMAKING",
"serviceKey": 5301,
"serviceSku": "PCH243",
"locationKey": 21076654,
"userKey": 202260
},
{
"projectId": "f71f8dab-2d35-4c83-aaa9-8eabc04f023a",
"partnerKey": 65,
"partnerOrderId": null,
"acquisitionKey": 338,
"status": "COMPANY_MATCHMAKING",
"serviceKey": 5301,
"serviceSku": "PCH243",
"locationKey": 1174179515,
"userKey": 202260
},
{
"projectId": "b78510f4-5ec8-42ec-856e-dfb568a98a20",
"partnerKey": 65,
"partnerOrderId": null,
"acquisitionKey": 2619,
"status": "COMPANY_MATCHMAKING",
"serviceKey": 5301,
"serviceSku": "PCH079",
"locationKey": 1174168781,
"userKey": 202260
}
],
"error": null
}
Request Validation
Summary of fields (query params):
- Required:
- userId or emailAddress
- Optional:
- limit: Maximum amount of results to see
- offset: Displacement between start and first shown element
- status: The status of projects to display (See Project Status)
- limit: Maximum amount of results to see
Get a Project by Id
GET /partner/project/{projectId}
$ curl -H 'X-Auth-Token: {your_api_key}' 'https://api.qa.porch.com/partner/project/1172a119-65af-441a-9d68-9a0325b7e537'
Example Response
{
"body": {
"projectId": "f71f8dab-2d35-4c83-aaa9-8eabc04f023a",
"partnerOrderId": "123xyz",
"connectionUrl": "http://qa.porch.com/connection/login/f71f8dab-2d35-4c83-aaa9-8eabc04f023a?redirect=/connection/f71f8dab-2d35-4c83-aaa9-8eabc04f023a",
"status": "COMPANY_MATCHMAKING",
"description": "I ordered the following product(s) from Walmart and would like to have them installed/assembled.\n\nCampaign: Service SKU\nPrepaid: true\n\nPorch SKU: PCH243\nPorch SKU Description: TV Wall Mounting (over 70\")\nPorch Service: TV Mounting\nPorch Service Price: null\n\nHomeowner Description: null",
"serviceType": {
"id": 5301,
"name": "TV Mounting",
"description": "The hanging or installation of a flat panel television using a tilting, telescoping, fixed, or adjustable mounting bracket",
"actorSingular": "tv mounting specialist",
"actorPlural": "tv mounting services",
"seoUrlPart": "tv-mounting"
},
"serviceSku": {
"serviceSku": "PCH243",
"serviceKey": 5301,
"description": "TV Wall Mounting (over 70\")",
"category": "Home Theater",
"nationwide": true,
"wholesale": null,
"fixedPrice": null,
"msrp": null,
"upc": 812060030268,
"marketingHeader": "Let Porch professionals get your new TV mounted and hooked up.",
"marketingCopy": "\"Who does the work?\n\nWe’ve partnered with Porch, the leading home services network, to offer you the convenience of installation and assembly services that you can buy with any applicable products or as a standalone service to help you get your project done. With real-time background check monitoring, licensing where required, and a one-strike policy you can rest easy knowing your service will be completed by the best pros in the business.\n\nHow does it work?\n\nSimply add any Porch service to your cart with a bundled product or as a standalone service and check out as usual. After your purchase, the pro who will perform your service will reach out to you to gather more details about your project and schedule the service at a convenient time for you. \n\nBacked by the Porch Guarantee\n\nPorch gives you peace of mind with the Porch Guarantee. All home improvement projects booked through Porch are backed by this guarantee so you can relax knowing that you're in good hands. We will get your job done right. If something isn’t right the first time, we’ll make it right whenever possible. Otherwise, we’ll refund you. Porch provides the most competitive pricing in the market. Receive a lower quote from a licensed, background-checked, satisfaction-guaranteed pro, and we’ll match the price.\"",
"included": "Installation of customer-supplied TV mount and mounting of TVs over 70\"\nLoad testing the hardware and securing the TV",
"notIncluded": null,
"imageUrl": "https://s3-us-west-2.amazonaws.com/porchcdn-prod/partner/skus/PCH079.jpg",
"partnerKey": null,
"directToBook": true
},
"address": {
"street1": "2200 1st Ave S",
"street2": null,
"city": "Seattle",
"state": "WA",
"postalCode": "98134"
},
"contact": {
"porchUserId": 202260,
"firstName": "Homer",
"lastName": "Owner",
"email": "homeowner@gmail.com",
"phone": "+12062345678"
},
"products": [
{
"quantity": 1,
"sku": "QWERTY01010101",
"name": "Name of Retail Product",
"description": "Description of retail product",
"url": "http://path.to/product/page",
"image": "http://path.to/product/image",
"instructions": "http://path.to/instructions",
"servicePriceShown": 4900
},
{
"quantity": 2,
"sku": "ASDF01234567",
"name": "Name of Another Retail Product",
"description": "Description of retail product",
"url": "http://path.to/product/page",
"image": "http://path.to/product/image",
"instructions": "http://path.to/instructions",
"servicePriceShown": 4900
}
],
"partner": {
"partnerKey": 65,
"partnerCode": "WALMART",
"displayName": "Walmart",
"authToken": "xxxxx",
"websiteUrl": "https://www.walmart.com/",
"logoUrl": "https://s3-us-west-2.amazonaws.com/porchcdn-prod/partner/logo/walmart.png",
"faviconUrl": null,
"bannerUrl": "https://cdn.porch.com/email/partner-banner/walmart-banner.png",
"supportEmail": null,
"supportPhone": null,
"acquisitionSourceKeys": [
93
]
},
"appointment": 1577865600,
"payment": {
"prepaid": true,
"refundEnabled": true,
"retailPriceCents": 4900,
"wholesalePriceCents": 3900
},
"externalAcquisitionId": "abc123"
},
"error": null
}
Summary of fields:
- Required:
- projectId: UUID of the project
Create a Simple Project
POST /partner/project/simple
$ curl -H 'Content-Type: Application/json' -H 'X-Auth-Token: {your_api_key}' -X POST -d '
{
"partnerOrderId": "123xyz",
"serviceTypeId": 6144,
"acquisitionKey": 339,
"acquisitionTrackingId": "abc123",
"externalAcquisitionId": "abc123",
"firstName": "Homer",
"lastName": "Owner",
"email": "homeowner@gmail.com",
"phone": "2062345678",
"phoneOptIn": true,
"contactPreference": "CALL",
"street1": "2200 1st Ave S",
"street2": null,
"city": "Seattle",
"province": "WA",
"postalCode": "98134",
"appointmentStartDateTime": 1577865600,
"quantity": 3,
"quotedHours": 2.5,
"retailPrice": 5900,
"wholesalePrice": 4900,
"products": [
{
"quantity": 1,
"sku": "QWERTY01010101",
"name": "Name of Retail Product",
"description": "Description of retail product",
"url": "http://path.to/product/page",
"image": "http://path.to/product/image",
"instructions": "http://path.to/instructions",
"servicePriceShown": 5900
},
{
"quantity": 2,
"sku": "ASDF01234567",
"name": "Name of Another Retail Product",
"description": "Description of retail product",
"url": "http://path.to/product/page",
"image": "http://path.to/product/image",
"instructions": "http://path.to/instructions",
"servicePriceShown": 5900
}
]
}
' 'https://api.qa.porch.com/partner/project/simple'
Example Response
{
"body":{
"projectId":"f1d0528e-76d9-4e7b-b57b-acfab9509e54",
"projectUrl":"https://www.porch.com/connection/login/f1d0528e-76d9-4e7b-b57b-acfab9509e54?redirect=/connection/f1d0528e-76d9-4e7b-b57b-acfab9509e54"
},
"error":null
}
Summary of fields:
- Required:
- firstName: First name of the customer
- lastName: Last name of the customer
- postalCode: Postal code where service is needed
- Required (must have one):
- email: Email address of the customer
- phone: Phone number of the customer
- Required (must have one):
- serviceTypeId: The key for the type of service needed
- porchServiceSKU: The sku for the type of service needed
- Required (must have one):
- acquisitionKey: Assigned By Porch,
- acquisitionTrackingId: Assigned By Porch,
- Optional:
- externalAcquisitionId: ID generated by the partner used to identify the acquisition source occurring outside of Porch (eg. an email campaign)
- street1: Street line 1 where service is needed
- street2: Street line 2 where service is needed
- city: City where the service will take place
- province: Province/State where service is needed
- phoneOptIn: Are calls allowed? Defaults to false
- contactPreference: CALL, EMAIL, TEXT or UNKNOWN (default)
- projectDetails: Any description or details about the project
- tcpaLanguage: Terms and conditions accepted language
- partnerOrderId: Any unique ID for this order, assigned by partner
- appointmentStartDateTime: Specify appointment date and time for managed fulfillment
- quantity: Number of service items requested
- quotedHours: Estimated hours per-item shown to homeowner
- retailPrice: Exact (possibly prepaid) per-item price shown to homeowner (cents)
- wholesalePrice: Per-item price paid to Porch by retail partner (cents)
- Products: Purchased items to be installed/assembled
- Product details (required)
- quantity: Quantity of this product purchased
- sku: Unique product identifier
- Product details (optional)
- name: Name of the product
- description: Description of the product
- url: URL of the product page
- image: URL of product image
- instructions: URL of installation instructions or user manual
- servicePriceShown: The price of service for this product (each) (cents)
Further validation:
- The customer email must be of a valid format and belong to a valid domain (MX record check performed)
- The customer phone must be a valid US phone number (verified by https://github.com/googlei18n/libphonenumber)
- The address must be recognized as deliverable (check https://smartystreets.com/)
- If the request includes street1, it must also include city, and province.
- If present, appointmentStartDateTime must be some time in the future.
Set Delivery Date
PUT /partner/project/{projectId}
$ curl -XPUT -H 'Content-Type: application/json' -H 'X-Auth-Token: {your_api_key}' \
https://api.qa.porch.com/partner/project/5f391449-f6a0-454d-9a55-d81959862480 -d '
{
"projectId": "5f391449-f6a0-454d-9a55-d81959862480,
"partnerProductSku": "QWERTY01010101",
"deliveryDate": ["2019", "10", "30"],
"trackingUrl": "http://shipping.carrier/tracking"
}'
Example Response
{
"body": "5f391449-f6a0-454d-9a55-d81959862480",
"error": null
}
Product delivery dates will be displayed to the homeowner and professional to aid in scheduling. Project leads will not be distributed to professionals until a delivery date is set on at least one associated product (either by calling this endpoint, or by specifying a deliveryDate in the initial project request).
Cancel a Project
PUT /partner/project/cancel
$ curl -XPUT -H 'Content-Type: application/json' -H 'X-Auth-Token: {your_api_key}' \
https://api.qa.porch.com/partner/project/cancel -d '
{
"reasonForCancellation": "Customer cancelled order"
}'
Example Response
{
"body": "5f391449-f6a0-454d-9a55-d81959862480",
"error": null
}
A project can be canceled while it’s still in the REQUIREMENTS_GATHERING, INSUFFICIENT_INFO, or COMPANY_MATCHMAKING state. It cannot be canceled if its in the PROJECT_EXECUTING, PROJECT_COMPLETED, or HOMEOWNER_CANCELLED state. A project cancellation incurs no penalty to the customer.
Request Parameters
ParameterName | Meaning |
---|---|
cancellationReason | A small note to describe the reason for canceling the project, if known. |
Cancel a Product
PUT /partner/project/{projectId}/product/cancel
$ curl -XPUT -H 'Content-Type: application/json' -H 'X-Auth-Token: {your_api_key}' \
https://api.qa.porch.com/partner/project/f39382eb-6dcf-485b-8a32-51f72a683330/product/cancel -d '
{
"sku":"PART1234",
"reasonForCancellation": "Customer cancelled order"
}'
Example Response
{
"body": "f39382eb-6dcf-485b-8a32-51f72a683330",
"error": null
}
Example Failure Response
{
"body": null,
"error": {
"code": "notFound",
"message": "Retail project does not exist",
"validationErrors": []
}
}
You can cancel products by the projectId and the sku of the product. It returns the project id of the cancelled product. The project will automatically be cancelled if all the products have been cancelled. Note: only cancel the product if all the items for that sku can been returned/cancelled.
Request Parameters
ParameterName | Meaning |
---|---|
sku | sku of the product being cancelled. |
cancellationReason | A small note to describe the reason for canceling the project, if known. |
Service Attach Widget
The Porch Service Attach Widget is the fastest way to get up and running with Porch Service integration.
Configure and Embed
Embed
The embed code for the widget consists of three parts:
- Javascript to initialize the widget.
script
tag for the widget bundle file. (NOTE: There are two bundles, one for QA and one for Production)- Empty
div
where the widget will be rendered.
<!-- 1. Javascript to initialize widget -->
<script type="text/javascript">
window.addEventListener("PorchWidgetLoad", function() {
window.Porch.ServiceAttachWidget.configure({
...
});
});
</script>
<!-- 2. script tag -->
<!-- Production -->
<script src="https://api.porch.com/wrapi/public/service-attach.js"></script>
<!-- QA -->
<script src="https://api.qa.porch.com/wrapi/public/service-attach.js" data-env="qa" id="porch-widget-client-script"></script>
<!-- 3. Empty div -->
<div id="porch-widget-body" class="porch-widget" />
Configuration
The Service Attach Widget can be configured with any of the options listed below. The Porch Widget Configuration App allows you to test different configurations of the widget, and get the complete embed code for the widget.
Parameter name | Description | Type |
---|---|---|
checkboxWrapperClassName |
CSS classname for the checkbox wrapped in span | string |
closeModalOnClickOutside |
Determines if the modal should close when clicked outside of the modal body, defaulted false | boolean |
ctaText |
The main text display in service attach widget | string |
customStyles |
Custom styles to overwrite default widget styles | object |
fontColor |
The color of the fonts display in widget | string |
fontFamily |
The font-family of the fonts display in widget | string |
fontSize |
The size of the fonts display in widget | string |
fontWeight |
The weight of the fonts display in widget | string |
isChecked |
Boolean the mark check box as checked | boolean |
onCloseAddToCartPopup |
A callback function that will be called when the customer close the Add-to-cart reminder | function |
onServiceAdd |
A callback function that will be called when customer has completed the form in the modal | function |
onServiceRemove |
A callback function that will be called when the customer “unchecks” the checkbox on the widget | function |
onWidgetOpenValidation |
A callback that receives a callback function as the only parameter, and can pass true or false to the callback to determine whether or not the modal should be opened. | function |
onWidgetRender |
A callback function that will be called when the widget has completed rendering in the browser. | function |
partnerName |
A unique partner name (this will be given to you by Porch) | string |
partnerSku |
The SKU for the product in your system. | string |
postalCode |
Customer’s postal code, if known, will be used to prepopulate a field in the modal form | string or number |
priceRangeWrapperClassName |
CSS classname for price range text | string |
productName |
The name for the product in your system. | string |
productUrl |
The url to the product on your website | string |
quantity |
The quantity of this product that the customer is purchasing. | string or number |
querySelector |
An optional DOM selector where the service attach widget will be rendered. if not provided, the widget will be rendered in the default porch markup container ( #porch-widget-body ) . This is required if you want to render multiple widgets on the same page ( each widget must use a different querySelector) |
string |
serviceFamilyCode |
A code string for the product’s service family | string |
serviceSkuCode |
A code string for the product’s service sku | string |
showPriceRange |
A boolean to configure the widget to show estimate price range | boolean |
priceShownLow |
Lower bound of the price shown in widget. This should be the same as the priceShownLow returned in modal payload |
string or number |
priceShownHigh |
Upper bound of the price shown in widget. This should be the same as the priceShownHigh returned in modal payload |
string or number |
useSinglePrice |
A boolean to configure the widget to show a single price, instead of a price range. Setting this to true will also mean the customer no longer gets modal on adding service. | boolean |
version |
Specifies which version of the payload the widget should return. When set to v3 , the widget will return payload specifically for partner project |
string |
custom styles
The service attach widget can be styled through the customStyles [object] props with given properties:
globalStyle
: styles that applies to the Service Attach Widget ModalmainHeader
: styles that applies to the main text in the header inside Service Attach Widget ModalbodyHeader
: styles that applies to the header in body inside Service Attach Widget ModalradioSelectLabelStyles
: styles that applies to the answers in the Service Attach Widget ModalradioSelectButtonOuterStyles
: styles that applies to the outter ring of the radio buttonradioSelectButtonSelectedOuterStyles
: styles that applies to the outter ring of the radio button when selectedradioSelectButtonSelectedInnerStyles
: styles that applies to the inner ring of the radio button when selectedbuttonStyles
: styles that applies to the add instllation buttonprimaryButtonColor
: primary color of the add installation buttonprimaryButtonHoverColor
: hover color of the add instlaation button
Example of the customStyles props
{
"globalStyle": {
"color": "#666"
},
"mainHeader": {
"color": "#273691",
"fontSize": "22px",
"marginTop": 0
},
"bodyHeader": {
"textTransform": "uppercase"
},
"radioSelectLabelStyles": {
"fontWeight": "normal"
},
"radioSelectButtonOuterStyles": {
"border": "2px solid #666"
},
"radioSelectButtonSelectedOuterStyles": {
"padding": 0,
"border": "none"
},
"radioSelectButtonSelectedInnerStyles": {
"background": "#273691"
},
"buttonStyles": {
":disabled": {
"background": "#00aef0",
":hover": {
"background": "#00aef0"
}
},
":active": {
"background": "#00aef0"
}
},
"primaryButtonColor": "#00aef0",
"primaryButtonHoverColor": "#00aef0"
}
Initialization
To initialize the Service Attach Widget, call window.Porch.ServiceAttachWidget.configure()
, and pass in an object with the desired configuration. The widget will emit a custom browser event named PorchWidgetLoad
to indicate that it is safe to call window.Porch.ServiceAttachWidget.configure()
.
<script type="text/javascript">
window.addEventListener("PorchWidgetLoad", function() {
window.Porch.ServiceAttachWidget.configure({
ctaText: "Get it installed",
fontFamily: "'Open Sans', Arial, Helvetica, sans-serif",
fontSize: "12px",
fontColor: "black",
serviceFamilyCode: "TV",
partnerName: "INTERNAL",
partnerSku: "TEST-SKU-ABC",
productName: "Test Product Name",
productUrl: "http://porch.com/product/test",
quantity: 1,
onServiceAdd: function(payload) {
// report the service Add to your backend/cart
},
onServiceRemove: function(payload) {
// report removal of the service to your backend/cart
},
onCloseAddToCartPopup: function() {
// Gets call when user close the add-to-cart reminder
},
onWidgetRender: function() {
// Widget has completed rendering
},
querySelector: 'div.user-panel.main input[name=serviceAttach]',
version: 'v3'
});
});
</script>
<script type="text/javascript" src="https://api.porch.com/wrapi/public/service-attach.js"></script>
<div id="porch-widget-body" class="porch-widget" />
Add/Remove Service Hooks
The Service Attach Widget has two hooks that are fired when a user adds or removes service to their order.
onServiceAdd
onServiceAdd Payload
{
"serviceType": 5301
"product": {
"name": "Test Product Name",
"priceShownHigh": 700,
"priceShownLow": 700,
"price": 700,
//price is used if useSinglePrice is set to true, but priceShownHigh and priceShownLow are also provided
"serviceSku": "PCH002",
"quantity": 1,
"sku": "TEST-SKU-ABC",
"url": "http://yoursite.com/product/#####"
}
}
This callback is fired by the widget when a user completes the modal form, indicating that they want to add Porch services to their order.
onServiceRemove
onServiceRemove Payload
{
"partnerSku": "TEST-SKU-ABC",
"productName": "Test Product Name",
"productUrl": "http://porch.com/product/test"
}
This callback is fired by the widget when a user unchecks the checkbox, after they’ve already invoked the Modal UI and added a Porch service, indicating that they no longer desire the service.
Add-to-cart reminder
Open Add-to-cart reminder
Example to open add-to-cart reminder
window.Porch.openAddToCartModal()
The window.Porch
object contains method to open the add-to-cart reminder:
window.Porch.openAddToCartModal()
Calling this method will open the add-to-cart reminder.
Close Add-to-cart reminder
onCloseAddToCartPopup function
{
onCloseAddToCartPopup: function () {
window.location.href = 'https://porch.com'
}
}
Clicking any of the following will close the Add-to-cart reminder:
‘No thanks’ button
Click 'X’ icon
Click anywhere outside of the modal reminder body
When user closes the reminder, the following function gets run:
onCloseAddToCartPopup
This is a function called by the widget when a user closes the Add-to-cart modal. Partners can pass in a specific function to run after the modal is closed.
Rendering multiple Service Attach widgets on the same page
The service attach widget supports multiple instances of the service attach widget on the same page, however, you must use the querySelector
prop in the configure method, and each querySelector
must be unique to each widget.
Service Attach Cart Widget
The Porch Service Attach Cart Widget is a convenient way for partners to report if a customer removes a Porch service from their cart.
Configuring the widget
This widget takes no configuration parameters, but we have chosen to leave the timing of its initialization to the end user. To initialize the widget, call window.Porch.ServiceAttachCartWidget.configure()
. The widget will emit a browser event to indicate that it is safe to call window.Porch.ServiceAttachWidget.configure()
.
example .configure() method call for the ServiceAttachCartWidget
window.addEventListener("PorchWidgetLoad", function() {
window.Porch.ServiceAttachCartWidget.configure();
});
removeFromCart method
In the event a customer chooses to remove Porch services from their cart on a cart or confirmation page, the window.Porch.ServiceAttachCartWidget.removeFromCart()
method will need to be called. It takes four of the parameters used to configure the Service Attach Widget for the product associated with the removed service:
partnerName
partnerSku
productName
serviceFamilyCode
example .removeFromCart() method call for the ServiceAttachCartWidget
window.Porch.ServiceAttachCartWidget.removeFromCart({
partnerName: "INTERNAL",
partnerSku: "TEST-SKU-ABC",
productName: "Test Product Name",
serviceFamilyCode: "TV"
});