The booking entity in PEAK 15 is used as a way to capture a group of guests that are traveling together on a specific departure. A new booking will generally result in the creation of one or more guest records as well as the creation of or updates to one or more contact records.


  • Create a Contact Booking
  • Using a Match Rule
  • Integrate Google Analytics
  • Booking Optional Prices
  • Booking Cost Item Reservations
  • Generating an Invoice
  • Processing a Credit Card Deposit
  • Creating a Credit Card Deposit for Later Processing
  • Page Redirect
  • Return All IDs
  • Creating a Booking Using a Departure Template
  • Update a Booking
  • Update a Contact Guest
  • Add or Remove an Optional Price from an Existing Guest
  • Add or Remove a Cost Item Reservation from an Existing Guest
  • Process Additional Guest Payments
  • Capture a Credit Card for a Guest
  • Capture a Credit Card for a Contact that isn't a Guest
  • Create Invoice Separately
  • Update an Invoice


Create a Contact Booking

The following post shows a basic booking on an existing departure. The 6th line will automatically add the contact as both the client (aka the main contact) on the booking as well as a guest (aka someone who is traveling).



https://data.peak15systems.com/beacon/service.svc/insert/complex/contactbooking
?token=yourtokenhere
&contact.firstname=[firstname]
&contact.lastname=[lastname]
&contact.emailaddress1=[email]
&contact.p15_contacttype_contactid=client
&p15_bookings.p15_tripdepartures_bookingsid=[departurename or departurecode or GUID]
&p15_guests.contact.1.isClient=true



Here is the same booking as an HTML form:


   

<html>
    <head>
        <title>Beacon Sample: Insert Contact Booking</title>
    </head>
    <body>
        <form action="https://data.peak15systems.com/beacon/service.svc/insert/complex/contactbooking"
              method="post" enctype="application/x-www-form-urlencoded">
            <input type="hidden" name="token" value="yourtokenhere" />
            <input type="hidden" name="contact.p15_contacttype_contactid" value="client" />
            <input type="hidden" name="p15_guests.contact.1.isClient" value="true" />
            <table>
                <tr>
                    <td align="left" colspan="2">
                        What departure would you like to book?
                        <select name="p15_bookings.p15_tripdepartures_bookingsid" size="1" style="width: 160px;">
                            <option value="">Select Departure</option>
                            <option value="[departurename or departurecode or GUID]">Departure 1</option>
                            <option value="[departurename or departurecode or GUID]">Departure 2</option>
                        </select>
                    </td>
                </tr>
                <tr>
                    <td width="300" align="left">
                        *First name
                    </td>
                    <td>
                        <input name="contact.firstname" id="firstname" type="text" size="15" maxlength="50" />
                    </td>
                </tr>
                <tr>
                    <td width="300" align="left">
                        *Last name
                    </td>
                    <td>
                        <input name="contact.lastname" id="lastname" size="15" maxlength="50" />
                    </td>
                </tr>
                <tr>
                    <td width="300" align="left">
                        *E-mail address
                    </td>
                    <td>
                        <input name="contact.emailaddress1" type="text" size="20" maxlength="100" />
                    </td>
                </tr>
                <tr>
                    <td width="300" height="30"></td>
                    <td>
                        <input type="submit" value="Submit" />
                </tr>
            </table>
    </body>
</html>



To add additional guests who are in the same household (aka share an address) include:


&p15_guests.contact.2.firstname=[firstname1]
&p15_guests.contact.2.lastname=[lastname1]
&p15_guests.contact.2.p15_contacttype_contactid=client
&p15_guests.contact.2.samehousehold=true



Using a Match Rule


By default, Beacon will create a new contact record in response to every contact inquiry that comes in. To reduce the number of duplicate records created, you can setup one or more duplicate detection rules inside PEAK 15 and then instruct Beacon to use one of those rules to evaluate whether to create a new contact or update an existing contact with any additional attributes provided and append the inquiry record to that contact. Note that your contact inquiry post must include values for all the attributes specified in the duplicate detection rule. For example, in the case of a request to send an email with a detailed itinerary of a specific trip where you are not collecting mailing address, a duplicate detection rule that checked for a match on first name and email address would be created inside PEAK 15. Adding this to your POST would then cause Beacon to check against that rule:


&contact.rule=[duplicate detection rule name]


or in the case of an HTML form:



<input type="hidden" name="contact.rule" value="[duplicate detection rule name]" />



Notes

Matches are case insensitive and the casing of data from the contact already in PEAK 15 is preserved since it is more likely to have the correct casing than a record entered on a website.

Null values sent in the post will not overwrite non-null values of the matched, pre-existing record.

If more than one active contact matches the values sent in the post, the new inquiry or booking will be appended to the active contact with the most recent booking, or if there is no booking, to the active contact with the most recent modified on date.

Any non-null contact attributes sent in the post will be written to the matching record returned. So if the last name were spelled differently, the last name would be updated to the value sent in the post. If you wish to avoid that, you can send another flag which instructs Beacon to check against the record it has identified as a match to see if that existing record has any other attributes that would be overwritten by values in the request. If the system finds that there are any non-null values that would be overwritten, then it will instead create a new contact record, but set its status reason to “Potential Duplicate” so that someone can review it to determine how to resolve the conflict.



To include that rule, just add:


&contact.ruletype=retainexistingvalues


or in the case of an HTML form:


<input type="hidden" name="contact.ruletype" value="retainexistingvalues" />



Integrate Google Analytics

If you use Google Analytics on your website, then we strongly recommend you take advantage of our integration that allows you to pass in data from Google Analytics about the inquiry such as the referring website’s name.


The integration relies upon javascript code that you add to your web form that will parse the cookie that Google leaves on your visitor’s computer. Those variables are then sent in with the inquiry as hidden form fields.


Note: Google's latest version of Google Analytics, known as Universal Analytics, captures this tracking information in a way that is not accessible by your website. However, there is a technique that will allow you to take advantage of all that Universal Analytics has to offer while maintaining the ability for your website to access this information. It relies upon having both versions of Google Analytics running side by side. To avoid confusion and possible double counting of traffic, you set the legacy tracking code using a generic account (e.g., UA-XXXYYYZZZ-1) and use Google Tag Manager to implement tracking for Universal Analytics.

There are 5 key variables to the cookie:

Google Analytics Variable
Description
PEAK 15 Attribute
Source 

Every referral to a web site has an origin, or source. Examples of sources are the Google search engine, the AOL search engine, the name of a newsletter, or the name of a referring web site. 
p15_bookings.p15_othersource
Term 
The term or keyword is the word or phrase that a user types into a search engine. Note that based on changes to Google and other search engine's policies, keyword data is generally no longer accessible. 

p15_bookings.p15_webkeywords


Campaign 
The campaign dimension differentiates product promotions such as "Spring Ski Sale" or slogan campaigns such as "Get Fit For Summer". 

p15_bookings.p15_webcampaign

 
Medium 
The medium helps to qualify the source; together, the source and medium provide specific information about the origin of a referral. For example, in the case of a Google search engine source, the medium might be "cost-per-click", indicating a sponsored link for which the advertiser paid, or "organic", indicating a link in the unpaid search engine results. In the case of a newsletter source, examples of medium include "email" and "print". 

p15_bookings.p15_webmedium


Content 
The content dimension describes the version of an advertisement on which a visitor clicked. It is used in content-targeted advertising and Content (A/B) Testing to determine which version of an advertisement is most effective at attracting profitable leads. 
p15_bookings.p15_webcontent



Here is a sample HTML form that has these hidden fields. Note line 2 where we call the populateHiddenFields function. A separate code snippet follows with the javascript you need to place inside the header tags of your form.


<form action="https://data.peak15systems.com/beacon/service.svc/insert/complex/contactbooking"
      method="post" enctype="application/x-www-form-urlencoded" onsubmit="populateHiddenFields(this);">
    <input type="hidden" name="token" value="yourtokenhere" />
    <input type="hidden" name="contact.p15_contacttype_contactid" value="client" />
    <input type="hidden" name="p15_guests.contact.1.isClient" value="true" />
    <input type="hidden" id='source' name='p15_bookings.p15_gasource' />
    <input type="hidden" id='medium' name='p15_bookings.p15_gamedium' />
    <input type="hidden" id='term' name='p15_bookings.p15_gaterm' />
    <input type="hidden" id='content' name='p15_bookings.p15_gacontent' />
    <input type="hidden" id='campaign' name='p15_bookings.p15_gacampaign' />
    <table>
        <tr>
            <td align="left" colspan="2">
                What departure would you like to book?
                <select name="p15_bookings.p15_tripdepartures_bookingsid" size="1" style="width: 160px;">
                    <option value="">Select Departure</option>
                    <option value="[departurename or departurecode or GUID]">Departure 1</option>
                    <option value="[departurename or departurecode or GUID]">Departure 2</option>
                </select>
            </td>
        </tr>
        <tr>
            <td width="300" align="left">
                *First name
            </td>
            <td>
                <input name="contact.firstname" id="firstname" type="text" size="15" maxlength="50" />
            </td>
        </tr>
        <tr>
            <td width="300" align="left">
                *Last name
            </td>
            <td>
                <input name="contact.lastname" id="lastname" size="15" maxlength="50" />
            </td>
        </tr>
        <tr>
            <td width="300" align="left">
                *E-mail address
            </td>
            <td>
                <input name="contact.emailaddress1" type="text" size="20" maxlength="100" />
            </td>
        </tr>
        <tr>
            <td width="300" height="30">

            </td>
            <td>
                <input type="submit" value="Submit" />
            </td>
        </tr>
    </table>
</form>


Here is the javascript to add in the head tag of your form which will create the "classic" cookie and then parse it and set the hidden form fields. NOTE: You only need to include the "Legacy Google Analtyics Tracking Code" portion of this sample code if you are using Universal Analytics! Also, if you are using Universal Analytics you will need to use Google Tag Manager to implement your tracking code to avoid confusion and duplication with the classic code.


<!-- Legacy Google Analytics Tracking Code left on purpose with generic act # to allow for integration-->
    <script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write("<script src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'>" + "</sc" + "ript>");
</script><script src="http://www.google-analytics.com/ga.js" type="text/javascript"></script>
    <script type="text/javascript">
try {
    var pageTracker = _gat._getTracker("UA-XXXYYYZZZ-1");
    pageTracker._trackPageview();
}
catch (err) { }
</script>
<!-- End Legacy Google Analytics -->
    <script type="text/javascript">
//
// This is a function that parses a string and returns a value.  We use it to get
// data from the __utmz cookie
//
function _uGC(l, n, s) {
    if (!l || l == "" || !n || n == "" || !s || s == "") return "-";
    var i, i2, i3, c = "-";
    i = l.indexOf(n);
    i3 = n.indexOf("=") + 1;
    if (i > -1) {
        i2 = l.indexOf(s, i); if (i2 < 0) { i2 = l.length; }
        c = l.substring((i + i3), i2);
    }
    return c;
}
//
// Get the __utmz cookie value. This is the cookie that
// stores all campaign information.
//
var z = _uGC(document.cookie, '__utmz=', ';');
//
// The cookie has a number of name-value pairs.
// Each identifies an aspect of the campaign.
//
// utmcsr  = campaign source
// utmcmd  = campaign medium
// utmctr  = campaign term (keyword)
// utmcct  = campaign content
// utmccn  = campaign name
// utmgclid = unique identifier used when AdWords auto tagging is enabled
//
// This is very basic code. It separates the campaign-tracking cookie
// and populates a variable with each piece of campaign info.
//
var source = _uGC(z, 'utmcsr=', '|');
var medium = _uGC(z, 'utmcmd=', '|');
var term = _uGC(z, 'utmctr=', '|');
var content = _uGC(z, 'utmcct=', '|');
var campaign = _uGC(z, 'utmccn=', '|');
var gclid = _uGC(z, 'utmgclid=', '|');
//
// The gclid is ONLY present when auto tagging has been enabled.
// All other variables, except the term variable, will be '(not set)'.
// Because the gclid is only present for Google AdWords we can
// populate some other variables that would normally
// be left blank.
//
if (gclid != "-") {
    source = 'google';
    medium = 'cpc';
}
var csegment = _uGC(document.cookie, '__utmv=', ';');
if (csegment != '-') {
    var csegmentex = /[1-9]*?\.(.*)/;
    csegment = csegment.match(csegmentex);
    csegment = csegment[1];
} else {
    csegment = '(not set)';
}
function populateHiddenFields(f) {
    f.source.value = source;
    f.medium.value = medium;
    f.term.value = term;
    f.content.value = content;
    f.campaign.value = campaign;
    //
    //The alerts below are handy for testing to ensure that the
    //campaign informaiton is getting correctly passed.
    //Once you've tested, just comment them out
    //
    alert('source=' + f.source.value);
    alert('medium=' + f.medium.value);
    alert('term=' + f.term.value);
    alert('content=' + f.content.value);
    alert('campaign=' + f.campaign.value);
    return false;
}
</script>



Booking Optional Prices

In this example, we create a booking with two guests as well as indicate that the first guest is booking two different optional prices and the second guest is booking one optional price:


&p15_guests.contact.1.p15_tripprices.1=[price1name or GUID]
&p15_guests.contact.1.p15_tripprices.2=[price2name or GUID]
&p15_guests.contact.2.p15_tripprices.2=[price2name or GUID]


Booking Cost Item Reservations

In this example, we add specific cost item reservations (for example, cabins) to each guest. Note that you can pass either the GUID or name of the cost item reservation as with prices:


&p15_guests.contact.1.p15_vendorserviceitemres.1=Cabin A1
&p15_guests.contact.2.p15_vendorserviceitemres.1=Cabin A1


Generating an Invoice

To have an invoice generated simply pass the name or GUID of the payment schedule for the invoice like this:


&p15_invoices.p15_paymentscheduleid=[paymentschedulename or GUID]



Processing a Credit Card Deposit

If you wish to redirect the visitor to Cybersource’s hosted secure credit card page where credit card payment can be securely processed without passing sensitive data over the wire, first confirm with support that this feature has been configured for your account and then simply add to your contactbooking post:


&amount=[decimal e.g. 500.00]
&currency=[currencycode e.g. USD]
&SuccessPage=https://data.peak15systems.com/SA2016/default.aspx?invoiceid


If you wish to test using a dummy card number, use Visa 4444-3333-2222-1111 and change the SuccessPage from default.aspx to defaulttest.aspx


&amount=[decimal e.g. 500.00]
&currency=[currencycode e.g. USD]
&SuccessPage=https://data.peak15systems.com/SA2016/defaulttest.aspx?invoiceid



Creating a Credit Card Deposit for Later Processing

If you don’t intend to charge the credit card until after the booking has been confirmed, you can redirect the visitor to Cybersource's hosted secure credit card page and have it capture the card information for later usage from within PEAK 15. This will result in a credit card record being added to the contact record of the client on the booking. Note that no payment is created. Only the credit card:


&amount=0
&currency=[currencycode e.g. USD]
&SuccessPage=https://data.peak15systems.com/SA2016/default.aspx?invoiceid
&satransactiontype=create_payment_token



If you wish to test using a dummy card number, use Visa 4444-3333-2222-1111 and change the SuccessPage from default.aspx to defaulttest.aspx


Page Redirect

Once you have tested your forms to ensure they are posting data to PEAK 15 correctly, you can use additional hidden form fields to define what pages on your site you’d like to send the submitter of the form in the event of a success or a failure.


&SuccessPage=http://domain.com/pg1.html
&Errorpage=http://domain.com/pg1.html



Or in the case of an HTML form:


<input type="hidden" name="SuccessPage" value="http://domain.com/pg1.html">
<input type="hidden" name="ErrorPage" value="http://domain.com/pg2.html">



NOTE: You can't combine usage of returnallids and the successpage/errorpage attributes.


Return All IDs

By default Beacon will return the GUID of the booking created. However, if you wish to get back the GUIDs of all records created or updated, then use:


&returnallids=true


Or in the case of an HTML form:


<input type="hidden" name="returnallIDs" value="true">



NOTE: You can't combine usage of returnallids and the successpage/error page attributes.

The response message will be a string like this:


contact=[contact GUID],p15_bookings=[booking GUID],p15_guests.contact.1.guestid=[guest GUID],
p15_guests.contact.2=[contact GUID],p15_guests.contact.2.guestid=[guest GUID]



Creating a Booking using a Departure Template

In the standard contactbooking posts, the booking is on a departure that has been previously created. This piece of the query string is what Beacon uses to determine which departure to book:


&p15_bookings.p15_tripdepartures_bookingsid=[departurename or departurecode or GUID]



In order to book a new departure based on a template provided you will replace that query string with:


&p15_tripdepartures.p15_tripdeparturesid=[GUID of departure template]
&p15_tripdepartures.p15_startdate=[date in mm/dd/yyyy format]


Note that we only support using the GUID of the departure template as that is assured to be unique whereas departurename may not be. Also, the departure template MUST BE ACTIVE in the system.


Beacon will, by default, keep the length of the departure it creates the same as the length of the template, but you can also control the duration or length by sending the following:


&p15_tripdepartures.p15_tourdays=[# of days]



Here is an example post that would result in a booking for a single guest on a new departure that was a copy of the specified departure template with July 1 2012 as the start date and duration of 5 days:


https://data.peak15systems.com/beacon/service.svc/insert/complex/
contactbooking?token=yourtokenhere
&contact.firstname=[firstname]
&contact.lastname=[lastname]
&contact.emailaddress1=[email]
&contact.p15_contacttype_contactid=client
&p15_tripdepartures.p15_tripdeparturesid=[GUID of departure template]
&p15_tripdepartures.p15_startdate=07/01/2012
&p15_tripdepartures.p15_tourdays=5
&p15_guests.contact.1.isClient=true


Another approach is to first make a copy of the departure using the following syntax and then use the returned departureID to book on it:


https://data.peak15systems.com/beacon/service.svc/insert/complex/copyDeparture
?token=yourtokenhere
&p15_tripdeparturesid=[GUID of departure template]
&p15_startdate=[date in mm/dd/yyyy format]



Update a Booking

The following post will take the GUID of an existing booking record and update attributes on the booking and add additional guests to the booking that share the same address as the client on the booking. Note that passing a blank value for an attribute causes that attribute to be ignored. If you wish to set the value of an attribute to NULL, you must use the ASCII value of '%00'.


https://data.peak15systems.com/beacon/service.svc/update/complex/contactbooking
?token=yourtokenhere
&contact.rule=[match rule name]
&p15_bookings.p15_bookingsid=[booking GUID]
&p15_bookings.p15_comment=Update to booking
&p15_bookings.statuscode=Booked
&p15_guests.contact.1.p15_contacttype_contactid=Client
&p15_guests.contact.1.firstname=[first name]
&p15_guests.contact.1.lastname=[last name]
&p15_guests.contact.1.samehousehold=true    
&p15_guests.contact.2.p15_contacttype_contactid=Client
&p15_guests.contact.2.firstname=[first name]
&p15_guests.contact.2.lastname=[last name]
&p15_guests.contact.2.samehousehold=true



Including this line will result in all existing guests on the booking being deleted


&deleteexistingguests=true



If you want to cancel a booking and all the guests on it:


https://data.peak15systems.com/beacon/service.svc/update/complex/contactbooking
?token=yourtokenhere
&p15_bookings.p15_bookingsid=[booking GUID]
&p15_bookings.p15_comment=Cancel reason
&p15_bookings.statuscode=Cancelled



Or if you want to delete a booking and all the guests on it:


https://data.peak15systems.com/beacon/service.svc/delete/entity/p15_bookings
?token=yourtokenhere
&p15_bookingsid=[booking GUID]



Or add a canceled guest to an existing booking:


https://data.peak15systems.com/beacon/service.svc/update/complex/contactbooking
?token=yourtokenhere
&p15_bookings.p15_bookingsid=[booking GUID]
&p15_guests.contact.1.p15_contacttype_contactid=Client
&p15_guests.contact.1.firstname=[first name]
&p15_guests.contact.1.lastname=[last name]
&p15_guests.contact.1.samehousehold=true
&p15_guests.contact.1.statuscode=Cancelled  



Update a Contact Guest

The following post will take the GUID of an existing guest record and update a combination of guest entity attributes like airline and arrival time as well as contact entity attributes like passport information. Note that passing a blank value for an attribute causes that attribute to be ignored. If you wish to set the value of an attribute to NULL, you must use the ASCII value of '%00'.


https://data.peak15systems.com/beacon/service.svc/update/complex/contactGuest
?token=[token]
&p15_guests.p15_guestsid=[guestGUID]
&p15_guests.p15_airline=[airline]
&p15_guests.p15_arrivaltime=[arrivaltime]
&contact.p15_nameonpassport=[passportname]


If you want to cancel a specific guest:


https://data.peak15systems.com/beacon/service.svc/update/entity/p15_guests
?token=[token]
&p15_guestsid=[guestGUID]
&statuscode=Cancelled
&p15_comments=Cancel reason


Or delete a specific guest:


Add or Remove an Optional Price from an Existing Guest

Once a booking has been created, you may use the following syntax to add optional prices to an existing guest's booking:


https://data.peak15systems.com/beacon/service.svc/insert/nn/p15_p15_tripprices_p15_guests
?token=[token]
&p15_guestsid=[guestGUID]
&p15_trippricesid=[trippriceGUID]


The following would remove an optional price from an existing guest's booking:


https://data.peak15systems.com/beacon/service.svc/delete/nn/p15_p15_tripprices_p15_guests
?token=[token]
&p15_guestsid=[guestGUID]
&p15_trippricesid=[trippriceGUID]


Add or Remove a Cost Item Reservation from an Existing Guest

Once a booking has been created, you may use the following syntax to add cost item reservations to an existing guest's booking:


https://data.peak15systems.com/beacon/service.svc/insert/nn/p15_p15_vendorserviceitemres_p15_guests
?token=[token]
&p15_guestsid=[guestGUID]
&p15_vendorserviceitemreservationid=[costitemresGUID]


The following would remove a cost item reservation from an existing guest's booking:


https://data.peak15systems.com/beacon/service.svc/delete/nn/p15_p15_vendorserviceitemres_p15_guests  
?token=[token]
&p15_guestsid=[guestGUID]
&p15_vendorserviceitemreservationid=[costitemresGUID]



Process Additional Guest Payments

In this example we process a credit payment from a guest who is paying their booking deposit separately from the rest of the group by simply sending the amount and currency attribute and a success page redirect value that will send the visitor to CyberSource's secure credit card page with some hidden values that allow that payment to be recorded properly by PEAK 15:


https://data.peak15systems.com/beacon/service.svc/update/complex/contactGuest
?token=yourtokenhere
&p15_guests.p15_guestsid=[guestGUID]
&amount=1
&currrecy=USD
&SuccessPage=https://data.peak15systems.com/SA2016/default.aspx?invoiceid



If you wish to test using a dummy card number, use Visa 4444-3333-2222-1111 and change the SuccessPage from default.aspx to defaulttest.aspx


Capture a Credit Card for a Guest

To simply capture the credit card information but not charge a payment, you would send:


https://data.peak15systems.com/beacon/service.svc/update/complex/contactGuest
?token=yourtokenhere
&p15_guests.p15_guestsid=[guestGUID]
&amount=0
&currency=USD
&SuccessPage=https://data.peak15systems.com/SA2016/default.aspx?invoiceid
&satransactiontype=create_payment_token



If you wish to test using a dummy card number, use Visa 4444-3333-2222-1111 and change the SuccessPage from default.aspx to defaulttest.aspx


Capture a Credit Card for a Contact that isn't a Guest

If you need to capture a Credit Card from a Contact who isn't a Guest, you should send the following (Note: you must send the invoiceid as all zeros):


http://data.peak15systems.com/SA2016/Default.aspx
?token=yourtokenhere
&invoiceid=00000000-0000-0000-0000-000000000000
&amount=0
&currency=USD
&contactid=[contactGUID]
&satransactiontype=create_payment_token


If you wish to test using a dummy card number, use Visa 4444-3333-2222-1111 and change the URL from default.aspx to defaulttest.aspx


Create Invoice Separately

Though the contact booking function provides a way to create an invoice automatically, there are situations where you need to be able to manually add items to an invoice that are not associated with pre-existing prices. In these cases you should not create the invoice during the booking and instead create the invoice separately with:


https://data.peak15systems.com/beacon/service.svc/insert/complex/invoice
?token=[yourtokenhere]
&p15_invoices.p15_contactid=[contactGUID]
&p15_invoices.p15_primarybookingid=[bookingGUID]
&p15_invoices.p15_paymentscheduleid=[paymentscheduleGUID]
&p15_invoiceitems.1.p15_name=[invoice item name]
&p15_invoiceitems.1.p15_categoryid=[price category name or GUID]
&p15_invoiceitems.1.p15_bookingsinvoiceitemsid=[booking GUID]
&p15_invoiceitems.1.p15_quantity=1
&p15_invoiceitems.1.p15_rate=250
&p15_invoiceitems.2.p15_name=[invoice item name]
&p15_invoiceitems.2.p15_categoryid=[price category name or GUID]
&p15_invoiceitems.2.p15_bookingsinvoiceitemsid=[booking GUID]
&p15_invoiceitems.2.p15_quantity=1
&p15_invoiceitems.2.p15_rate=100


Note that you DO NOT need to manually add invoice items for those prices booked by guests. Those will be added for you automatically.


To delete an invoice:


https://data.peak15systems.com/beacon/service.svc/delete/entity/p15_invoices
?token=[yourtokenhere]
&p15_invoicesid=[invoiceGUID]



Update an Invoice

Rather than deleting an Invoice and reinserting a new one, you can also update it. The advantage of updating the invoice is that it allows the Invoice history to be maintained. Updating an Invoice in Beacon follows the same rules that apply to users trying to update an Invoice inside the application. If an Invoice has a status of Approved, Downloaded or Entered, then updating the invoice requires that it be revised. Revising an invoice causes a new replacement invoice to be created and an offsetting credit memo (or negative invoice) to be created and applied to the old invoice and any payments on the old invoice to be moved to the new invoice.


https://data.peak15systems.com/beacon/service.svc/update/complex/invoice
?token=[yourtokenhere]
&p15_invoices.p15_invoicesid=[GUID of invoice]
&deleteexistinginvoiceitems=[true/false (defaults to false if not specified, set to true if you will be sending in all invoice items manually)]
&p15_invoices.p15_createinvoiceitems=[true/false (defaults to true if not specified, set to false if you will be sending in all invoice items manually)]
&p15_invoiceitems.1.p15_name=[invoice item name]
&p15_invoiceitems.1.p15_categoryid=[price category name or GUID]
&p15_invoiceitems.1.p15_bookingsinvoiceitemsid=[booking GUID]
&p15_invoiceitems.1.p15_quantity=1
&p15_invoiceitems.1.p15_rate=250
&p15_invoiceitems.2.p15_name=[invoice item name]
&p15_invoiceitems.2.p15_categoryid=[price category name or GUID]
&p15_invoiceitems.2.p15_bookingsinvoiceitemsid=[booking GUID]
&p15_invoiceitems.2.p15_quantity=1
&p15_invoiceitems.2.p15_rate=100



The "normal" usage of the system would be to set deleteexistinginvoicetiems to false, createinvoiceitems to true and then to only send in invoice items for anything that is being manually added to the booking such as a special discount or one off service. If the invoice ID sent in doesn't exist or has a status of Disapproved, an error will be returned. If the status is Submitted, it will update the invoice based on the flags set and any additional invoice items sent it. If the status is Approved, Downloaded or Entered, it will revise the invoice as described above.


https://data.peak15systems.com/beacon/service.svc/delete/entity/p15_guests
?token=[token]
&p15_guestsid=[guestGUID]